659. 分割数组为连续子序列
原始题目链接:https://leetcode.cn/problems/split-array-into-consecutive-subsequences/
给你一个按升序排序的整数数组 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
解题思路:
哈希表+最小堆的数据结构,如果存在比当前元素nums小1的数字为结尾的子序列,将当前数字作为新的子序列的结尾,并且长度+1,入堆操作是更新以当前元素为结尾的堆顶元素。不存在比当前元素nums小1的数字为结尾的子序列,新建一个长度为1的以当前元素为结尾的子序列。
代码实现:
class Solution:
def isPossible(self, nums: List[int]) -> bool:
# 哈希表的键是nums中的数字,值是最小堆数据结构
# 堆顶存储的是子序列的长度
hash_table = collections.defaultdict(list)
for num in nums:
# 海象运算符
# 如果存在比当前元素nums小1的数字为结尾的子序列
if heap := hash_table.get(num - 1):
# 将当前数字作为新的子序列的结尾,并且长度+1
pre_len = heapq.heappop(heap)
heapq.heappush(hash_table[num], pre_len + 1)
else:
# 不存在比当前元素nums小1的数字为结尾的子序列
# 新建一个长度为1的以当前元素为结尾的子序列
heapq.heappush(hash_table[num], 1)
# any操作符只要都为False,返回False,有一个为True,返回True
# not 为取反
return not any(heap and heap[0] < 3 for heap in hash_table.values())
参考文献:
https://leetcode.cn/problems/split-array-into-consecutive-subsequences/solution/fen-ge-shu-zu-wei-lian-xu-zi-xu-lie-by-l-lbs5/