这是我参与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(), []))