【leedcode】659. 分割数组为连续子序列

263 阅读1分钟

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战

难度: 中等

题目简介

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

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

1 <= nums.length <= 10000

思路一:

两个dict记录,第一个dict记录 nums 中的数字计数,第二个为{}

  • 出现了新的数字,看之前是否有一个子序列比这个数字小1,可以让这个数字接在这个子序列后面。
    • 如果可以,更新这个子序列的结尾变为这个新数字
  • 看这个新数字后面是否有两个数字,分别比这个数字大1和大2。
    • 有: 这两个数字的次数减1,并且出现了一个新的子序列,其结尾为这个新数字。
    • 没有 返回False,每次遍历都需要将这个新数字的次数减1.最开始的continue是因为有些后面的数字变用掉了。

class Solution:
    def isPossible(self, nums: List[int]) -> bool:
        count = collections.Counter(nums)
        end = collections.Counter()
        for num in nums:
            if count[num] == 0:
                continue
            elif end[num-1] > 0:
                end[num-1] -= 1
                end[num] += 1
            elif count[num+1] > 0 and count[num+2] > 0:
                count[num+1] -= 1
                count[num+2] -= 1
                end[num+2] += 1
            else:
                return False
            count[num] -= 1
        return True

思路二:

堆+哈希表

1.初始一个字典dct。 2.循环nums:判定是否可以合并 可以则合并,不可则新增连续子序列。


class Solution:
    def isPossible(self, nums: List[int]) -> bool:
        dct = {}
        for i in nums:
            if i-1 not in dct:
                if i in dct:
                    heappush(dct[i], 1)
                else:
                    dct[i] = [1]
                    heapify(dct[i])
            else:
                if len(dct[i-1]) == 1:
                    p = dct[i-1][0]
                    del dct[i-1]
                else:
                    p = heappop(dct[i-1])
                if i in dct:
                    heappush(dct[i], p+1)
                else:
                    dct[i] = [p+1]
                    heapify(dct[i])
        return all(i >= 3 for i in sum(dct.values(), []))