当前位置:   article > 正文

哈希,LeetCode 2007. 从双倍数组中还原原数组

哈希,LeetCode 2007. 从双倍数组中还原原数组

一、题目

1、题目描述

一个整数数组 original 可以转变成一个 双倍 数组 changed ,转变方式为将 original 中每个元素 值乘以 2 加入数组中,然后将所有元素 随机打乱 。

给你一个数组 changed ,如果 change 是 双倍 数组,那么请你返回 original数组,否则请返回空数组。original 的元素可以以 任意 顺序返回。

2、接口描述

python3
  1. class Solution:
  2. def findOriginalArray(self, changed: List[int]) -> List[int]:
cpp
  1. class Solution {
  2. public:
  3. vector<int> findOriginalArray(vector<int>& changed) {
  4. }
  5. };

3、原题链接

2007. 从双倍数组中还原原数组 - 力扣(LeetCode)


二、解题报告

1、思路分析

我们考虑将数组排序后会是什么样子?

a ... a  2a... 2a  c ... c  d ... d 2d ……

那么我们有一种O(nlogn)做法(也是我第一次做的时候的做法),将数组排序,然后哈希统计

然后从小到大遍历数组,用x排除2x,如果出现某个元素仍有剩余那就返回空,不然就是一个目标数组,我们在遍历的时候添加元素到返回数组即可

然后看到题解有O(n)做法

事实上不需要排序,只需哈希计数

我们发现我们只要拿到a,就能排除2a,4a……

那么我们哈希 统计后,遍历哈希表,如果x不存在x / 2在哈希表中,说明它可能是某个连续序列的起点,我们从x往下一直排除2x,4x……

如果存在cnt[x] > cnt[2x]就返回空数组

2、复杂度

时间复杂度: O(n)空间复杂度:O(n)

3、代码详解

python3
  1. class Solution:
  2. def findOriginalArray(self, changed: List[int]) -> List[int]:
  3. mp = Counter(changed)
  4. cnt0 = mp.pop(0, 0) # default = 0,不存在0返回0
  5. if cnt0 & 1:
  6. return []
  7. ret = [0] * (cnt0 // 2)
  8. for x in mp:
  9. if x % 2 == 0 and x // 2 in mp:
  10. continue
  11. while x in mp:
  12. cnt = mp[x]
  13. if cnt > mp[x * 2]:
  14. return []
  15. ret.extend([x] * cnt)
  16. if cnt < mp[x * 2]:
  17. mp[x * 2] -= cnt
  18. x *= 2
  19. else:
  20. x *= 4
  21. return ret
cpp
  1. class Solution {
  2. public:
  3. vector<int> findOriginalArray(vector<int>& changed) {
  4. if(changed.size() & 1) return {};
  5. unordered_map<int, int> mp;
  6. int cnt0 = 0;
  7. for(auto x : changed) mp[x] ++, cnt0 += !x;
  8. if(cnt0 & 1) return {};
  9. mp.erase(0);
  10. vector<int> ret(cnt0 / 2);
  11. for(auto [k, _] : mp){
  12. int x = k;
  13. if(x & 1 || !mp.count(x / 2)){
  14. while(mp.count(x)){
  15. int cnt = mp[x];
  16. if(cnt > mp[x * 2]) return {};
  17. ret.insert(ret.end(), cnt, x);
  18. if(mp[x << 1] > cnt) mp[x << 1] -= cnt, x <<= 1;
  19. else x <<= 2;
  20. }
  21. }
  22. }
  23. return ret;
  24. }
  25. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/490345
推荐阅读
相关标签
  

闽ICP备14008679号