class Solution:
def findOriginalArray(self, changed: List[int]) -> List[int]:
cnt = Counter(changed)
# 单独处理 0
cnt0 = 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 个 2x
if cnt_x > cnt[x * 2]:
return []
ans.extend([x] * cnt_x)
if cnt_x < cnt[x * 2]:
# 还剩下一些 2x
cnt[x * 2] -= cnt_x
x *= 2
else:
x *= 4
return ans
解释: 此类问题可以分组 并且可以根据某些条件判断组别起始点,遍历Counter()的键,如果满足条件则从该键行进算法逻辑,如果不满足条件则跳过直到寻找到起始点。
128题思路也是如此,数组的每个序列都一定有一个起始点,如果遍历到某点,判断该点元素-1是否在Counter()中,如果在,那就不是起始点,如果不是就从该点出发判断。
分组的思想也体现在了2982题中。