[leetcode每日一題2021/2/13]448. 找到所有陣列中消失的數字
阿新 • • 發佈:2021-02-14
找到所有陣列中消失的數字
題目來源於leetcode,解法和思路僅代表個人觀點。傳送門。
難度:簡單
時間:-
題目
給定一個範圍在 1 ≤ a[i] ≤ n ( n = 陣列大小 ) 的 整型陣列,陣列中的元素一些出現了兩次,另一些只出現一次。
找到所有在 [1, n] 範圍之間沒有出現在陣列中的數字。
您能在 不使用額外空間且時間複雜度為O(n) 的情況下完成這個任務嗎? 你可以假定返回的陣列不算在額外空間內。
示例:
輸入:
[4,3,2,7,8,2,3,1]
輸出:
[5,6]
思路
不使用額外空間且時間複雜度為O(n),即進行一次遍歷+使用指標(或原地修改陣列)
原地雜湊
思路來源於之前做過的一道題41. 缺失的第一個正數
咋一看,題目非常類似,所以稍微想了一想,嘗試使用原地雜湊的方法
維護一個對映關係:將n對映到陣列的n-1的位置上
之後再進行一次遍歷,如果當前位置的元素不滿足對映關係,當前位置的元素就為缺失。
程式碼
class Solution {
public:
template <typename T>
void swap(T &a,T &b){
T temp;
temp = a;
a = b;
b = temp;
}
vector< int> findDisappearedNumbers(vector<int>& nums) {
vector<int> ans;
//陣列長度
int n = nums.size();
//對映條件:n對映到 陣列n-1的位置
for(int p=0;p<n;p++){
//n-1位置上的數,不為n,交換二者
/*
* 1. 為什麼使用while?
* 交換後,當前位置的元素可能又不滿足對映條件,所以還需要繼續交換
* 2. 結束之後的狀態?
* (1)當前位置的元素,恰好滿足對映條件。
* 如:1 3 2 => 1 2 3(指標p為1,交換3-2之後,滿足對映關係)
* (2)當前位置的元素,不滿足對映條件。但對應位置的元素已經滿足對映關係了。
* 如:1 3 3 => 1 3 3 (指標p為1,nums[3-1]恰好==3,不需要交換)
*/
while(nums[nums[p]-1] != nums[p]){
swap(nums[p],nums[nums[p]-1]);
}
}
//再進行一個遍歷
for(int p=0;p<n;p++){
//如果當前位置的元素不滿足對映關係,加入答案
if(nums[p] != p+1){
ans.push_back(p+1);
}
}
return ans;
}
};
演算法複雜度
時間複雜度: O(n),最壞O(2n)。while迴圈在第一個元素的時候,先把所有元素都對映好了
空間複雜度: O(1),答案不計算在空間複雜度中,使用原陣列原地修改的策略。