惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Blog — PlanetScale
Blog — PlanetScale
小众软件
小众软件
F
Fortinet All Blogs
博客园 - 叶小钗
博客园_首页
D
DataBreaches.Net
Apple Machine Learning Research
Apple Machine Learning Research
U
Unit 42
爱范儿
爱范儿
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
IT之家
IT之家
M
MIT News - Artificial intelligence
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog

OhYee 博客

小鹏辅助驾驶测评|OhYee 博客 小鹏非支持手机开启自动解锁|OhYee 博客 使用函数计算实现 301 重定向|OhYee 博客 针对 HTML 内容使用 Ant Design 图片弹框|OhYee 博客 博客进程泄露及僵尸进程解决|OhYee 博客 蓝易云服务器体验|OhYee 博客 SSH 调起本地 VSCode|OhYee 博客 【2022 秋招内推】阿里云后端研发工程师|OhYee 博客 使用函数计算获取 IP 地址信息|OhYee 博客 正确获取客户端 IP/HTTP Header 也可能重复|OhYee 博客 评测 Oculus Quest2 及 BigScreen|OhYee 博客 NextJS 热重载保留状态|OhYee 博客 如何优雅地贴 gist 代码|OhYee 博客 Linux 精细化文件权限|OhYee 博客 VSCode 容器开发环境|OhYee 博客 Clash 的不兼容更新排查|OhYee 博客 Zeek 导出 PCAP|OhYee 博客 记一次 ssh 配置问题|OhYee 博客 Git Commit 规范化工具|OhYee 博客 谈谈《星之卡比-探索发现》|OhYee 博客 VSCode 快捷键绑定 Shell 命令|OhYee 博客 ASN.1 语法及 X.509 证书格式解析解析|OhYee 博客 腾讯企业邮箱忽略 MX 记录发信|OhYee 博客 Chrome/Edge 标签组插件|OhYee 博客 【应届内推】阿里云后端研发工程师|OhYee 博客 损坏的 Typecho 备份处理为 JSON|OhYee 博客 VS Code VIM 插件高效使用|OhYee 博客 SSH 正反向代理|OhYee 博客 Let's Encrypt 根证书过期引发的问题|OhYee 博客 OpenWRT 忽略内核依赖|OhYee 博客
LeetCode 659. 分割数组为连续子序列|OhYee 博客
2020-12-06 · via OhYee 博客

这是一篇最后编辑于 6 年前 的文章,其内容可能与目前实际情况差异较大,请注意甄别

LeetCode 659. 分割数组为连续子序列

题目描述

给你一个按升序排序的整数数组num(可能包含重复数字),请你将它们分割成一个或多个长度为3的子序列,其中每个子序列都由连续整数组成。

如果可以完成上述分割,则返回true;否则,返回false

示例一

输入: [1,2,3,3,4,5]
输出: True
解释:
你可以分割出这样两个连续子序列 :
1, 2, 3
3, 4, 5

示例二

输入: [1,2,3,3,4,4,5,5]
输出: True
解释:
你可以分割出这样两个连续子序列 :
1, 2, 3, 4, 5
3, 4, 5

示例三

输入: [1,2,3,4,4,5]
输出: False

题解

首先按照贪心的思路考虑该问题:

  • 新的数应该尽可能把连续 2 个的数凑到满 3 个(如果凑不够,就要直接返回false
  • 当所有的 2 个数都凑到满 3 个后,尽可能把 1 个的数凑到满 2 个(如果凑不够,直接返回false)
  • 当所有的 1 个都凑到 2 个后,把剩下的数尽可能和之前已经凑成一组(这样不会引入新的连续 1 个数,同时后面的连续的数也可以继续向后续)
  • 只有还有多余的数必须单独成组,成为新的连续 1 个的

综上所述,只需要按照要求维护“连续 1 个”,“连续 2 个”,“连续 3 个以上”的个数即可

LeetCode 题解里有人给出了时间复杂度 O(n)O(n),空间复杂度 O(1)O(1) 的解法,相当于下面代码修改为一边计算个数,一边进行判断的情况。

代码

class Solution:
    def isPossible(self, nums: List[int]) -> bool:
        if len(nums) == 0:
            return True
        count = {}
        for n in nums:
            count[n] = count.get(n, 0) + 1

        pre = -1
        l = [0, 0, 0, 0]
        for i in range(min(nums), max(nums) + 1):
            if pre == -1:
                # 没有前一个数
                if count.get(i, 0) > 0:
                    # 当前数有值,则更新为当前数
                    l[1] = count[i]
                    l[2] = 0
                    l[3] = 0
                    pre = i
                else:
                    continue
            else:
                if count.get(i, 0) == 0:
                    # 存在前一个数,同时当前数不存在
                    if l[1] != 0 or l[2] != 0:
                        # 还有没凑够 3 个的数
                        return False
                    else:
                        # 全部都凑够 3 个,从新开始
                        l[3] = 0
                        pre = -1
                        continue
                else:
                    c = count[i]
                    temp = l[3]
                    # 优先凑 3 个
                    if c >= l[2]:
                        # 足够把 2 个的都凑成 3 个
                        c -= l[2]
                        l[3] = l[2]
                        if c >= l[1]:
                            # 足够把所有 1 个的凑成 2 个
                            c -= l[1]
                            l[2] = l[1]
                            if c > temp:
                                # 剩下的都补给原本就有 3 个的仍有剩余
                                l[1] = c - temp
                                l[3] += temp
                            else:
                                # 剩下的都补给原本就有 3 个的
                                l[1] = 0
                                l[3] += c
                        else:
                            # 只能把部分 1 个凑成 2 个
                            return False
                    else:
                        # 只能把部分 2 个凑成 3 个
                        return False
        return l[1] == 0 and l[2] == 0