2007. 从双倍数组中还原原数组
class Solution:def findOriginalArray(self, changed: List[int]) -> List[int]:cnt = Counter(changed)# 单独处理 0cnt0 = cnt.pop(0, 0)if cnt0 % 2:return []ans = [0] * (cnt0 // 2)for x in cnt:# 如果 x/2 在 cnt 中,则跳过if x % 2 == 0 and x // 2 in cnt:continue# 把 x, 2x, 4x, 8x, ... 全部配对while x in cnt:# 每次循环,把 cnt_x 个 x 和 cnt_x 个 2x 配对cnt_x = cnt[x]# 无法配对,至少要有 cnt_x 个 2xif cnt_x > cnt[x * 2]:return []ans.extend([x] * cnt_x)if cnt_x < cnt[x * 2]:# 还剩下一些 2xcnt[x * 2] -= cnt_xx *= 2else:x *= 4return ans
解释: 此类问题可以分组 并且可以根据某些条件判断组别起始点,遍历Counter()的键,如果满足条件则从该键行进算法逻辑,如果不满足条件则跳过直到寻找到起始点。
128题思路也是如此,数组的每个序列都一定有一个起始点,如果遍历到某点,判断该点元素-1是否在Counter()中,如果在,那就不是起始点,如果不是就从该点出发判断。