字串型別的內建方法(二)
阿新 • • 發佈:2021-11-08
找出陣列中重複的數字。
在一個長度為 n 的陣列 nums 裡的所有數字都在 0~n-1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意一個重複的數字。
方法1:雜湊表
class Solution { public: int findRepeatNumber(vector<int>& nums) { vector<int> hashNum(nums.size(), 0); //雜湊表儲存數字出現的次數; for(auto x : nums){ if(hashNum[x]) //出現了就返回; return x; hashNum[x]++; //沒出現就新增進去; } return -1; } };
時間複雜度:$ O(n) $ ,空間複雜度:$ O(n)$
方法2:原地交換
將每一個數字放回到自己的位置,當掃描到下標為 \(i\) 的數字 \(num[i]\) 時,如果 $num[i]==i $,說明該數字放在了正確的位置上,否則的話看一下它本來應該在的位置 \(num[i]\) ,即 \(num[num[i]]\) 上的數字為多少,二者相等的話說明出現了重複,不相等的話就交換一下。
class Solution { public: int findRepeatNumber(vector<int>& nums) { int len = nums.size(); for(int i = 0; i < len; i++){ while(nums[i] != i){ if(nums[i] == nums[nums[i]]) return nums[i]; else swap(nums[i],nums[nums[i]]); } } return -1; } };
時間複雜度:$ O(n) $ ,空間複雜度:$ O(1)$
拓展題:不修改陣列找出重複的數字
在一個長度為n+1的陣列 nums 裡的所有數字都在 1~n 的範圍內。所以陣列中至少有一個數字是重複的。請找出陣列中任意一個重複的數字。
不修改陣列,不新增陣列,使用二分法。該方法不保證找到所有的重複數字,比如:{2,3,5,4,3,2,6,7}。
class Solution { public: int findRepeatNumber(vector<int>& nums) { int left = 1, right = nums.size() - 1; while(left <= right){ int middle = ((right - left) >> 1) + left; int count = conutNums(nums, left, middle); if(left == right){ if(count > 1) return left; else break; } if(count > (middle - left + 1)) right = middle; else left = middle + 1; } return -1; } int conutNums(vector<int>& nums, int left, int right){ int count = 0; for(auto n : nums){ if(n >= left && n <= right) count++; } return count; } };