1. 程式人生 > 其它 >[leetcode每日一題2021/2/13]448. 找到所有陣列中消失的數字

[leetcode每日一題2021/2/13]448. 找到所有陣列中消失的數字

技術標籤:演算法leetcode

找到所有陣列中消失的數字

題目來源於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),答案不計算在空間複雜度中,使用原陣列原地修改的策略。

在這裡插入圖片描述