深思數盾助力海康機器人,全新VM4.2乘風破浪,安全起航
阿新 • • 發佈:2022-03-30
•題目連結
•題意
給定一個包含 n 個數的整數陣列,其中陣列中的數字的取值範圍為 [0~n-1],讓你從中找出任意一個重複的數字。
•解法一:雜湊
演算法描述
通過 unordered_map 判斷是否重複。
複雜度
- 時間複雜度: O(n)
- 空間複雜度:O(n)
CODE
class Solution { public: int findRepeatNumber(vector<int>& nums) { unordered_map<int, bool>mymap; mymap.clear(); vector<int >::iterator it; for (it = nums.begin(); it != nums.end(); it++) { int num = *it; if (mymap.count(num))//判斷num是否已存在 return num; mymap[num] = true; } return -1; } };
•解法二:原地交換
演算法描述
由於所有的數字都在 [0, n-1] 的範圍內,因此如果沒有重複,那麼所儲存的值也正好是 [0, n-1] 這 n 個數字。
我們把原陣列重新排列為 索引—值 相對應的陣列。
對於如下陣列:
重新排列後:
也就是說,重排後的結果是 索引—值 一一對應。
基於此,我們設計如下演算法:
- 從頭到尾遍歷整個陣列,當掃描到下標為 index 時,首先比較該位置的 索引(index) 與 值(記為 val) 是否相等:
- 如果相等,說明 index-value 已經歸位,接著比較下一個位置
- 如果不相等,將 val 歸位,即 nums[index] 與 nums[val] 交換
- 交換後繼續執行上述步驟,直到 index 位置的 索引—值 相等為止
- 重複上述步驟,直到遍歷完整個陣列
當遍歷完整個陣列後,就實現了所有位置的 索引—
值 一一對應。由於題目中給出的資訊是一定存在重複的數字,那麼,只需要在將 val 歸位的時候,判斷 val 與 nums[val] 是否相等,如果相等,那麼 val 就是一個重複數字,返回即可。
複雜度分析
- 時間複雜度:O(n)
- 最壞的情況就是陣列元素逆序,此時需要的遍歷兩邊陣列,即 O(2n)
- 空間複雜度:O(1)
CODE
class Solution { public: int findRepeatNumber(vector<int>& nums) { int index = 0; //對於 index 位置,將 nums[index] 歸位,並在歸位是判斷是否重複 while (index < nums.size()) { int val = nums[index]; if (index == val)//index處的 索引—值 已對應 { index++; continue; } //若 val 未歸位,將其歸位 if (val == nums[val])//歸位前判斷 val 是否重複 return val;//返回重複元素 swap(nums[index], nums[val]);//交換,並重覆上述過程,直到 nums[index] = index } return -1;//無重複元素返回 -1,當然本題是不存在這種情況的 } };