leetcode-645 leetcode-442 總結-------“數組”查找重複數系列

引言

有些關於數組的題目說難不難,說簡單的話也非常不簡單,如果稍微在數組操作中加一些限制條件,比如時間複雜度只能是O(n),空間複雜度只能是O(1)或者O(n),那麼這樣的題就跟數學題和智力題一樣很考驗人。

類似題目

leetcode-645 錯誤的集合;leetcode-442 數組中重複的元素;

解題思路:

剛開始的時候,我之前都是第一印象是對原來數組進行排序,這樣一來數組中的數據假如題目中給的數據是【1-n】的話,那麼大概可以各自歸位了,即nums[i]=i+1.但是呢,這樣的方法是不可取的,一是因爲假如重複的數如果在排序之後並不是挨着的,例如LeetCode-645中的一個測試用例【3,2,3,4,6,5】,重複的3和缺少的1就沒有挨着。所以經過查看網上大神們的做題思路,感覺很新奇:

他們並不是對原來的數據進行修改,而是對其符號進行修改,遇到nums[i]那麼就把下標爲nums[i]-1的這個元素符號進行反轉:

  • 如果爲正,那麼就把下標爲nums[i]-1的元素符號更換
  • 如果爲負,說明之前下標爲nums[i]-1的元素已經存在了,那麼就可以立馬找到重複的那個數就是nums[i].就可以直接把重複的結果找到。

例如leetcode-645 錯誤的集合:參考https://blog.csdn.net/woshichaoren000/article/details/76147116的傑作:

vector<int> findErrorNums(vector<int>& nums) {
        vector <int> ans;
        for (int i = 0; i < nums.size(); i++) {
            int index = abs(nums[i]) - 1;
            if (nums[index] > 0) {
                nums[index] *= -1;
            }
            else {
                ans.push_back(index + 1);
            }
        }
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] > 0) {
                ans.push_back(i + 1);
            }
        }
        return ans;
    }

就是我剛纔說的思路。

leetcode-442使用相同的思路完全可以解決,而且時間複雜度只有O(N),空間複雜度只有O(1)。參考大神https://blog.csdn.net/bengepai/article/details/79200450的代碼入下:

vector<int> findDuplicates(vector<int>& nums) {
        vector<int> result;
        for(int i=0;i<nums.size();i++)
        {
            nums[abs(nums[i])-1]=-nums[abs(nums[i])-1];//將當前值所對應的索引的值變爲相反數。
            if(nums[abs(nums[i])-1]>0)//大於0,說明該數變過2次,說明對應的索引出現了2次,索引即爲重複數字(因爲沒有5,6所以他根本不會查看5,6的下標是否爲正負,所以就可以解決,6,5對應下標也是正數的情況)
                result.push_back(abs(nums[i]));
        }

        return result;
    }

所以,當對簡單數組操作的時候,有時候並不簡單,稍微加一個限制條件就有可能難道一個新高度。所以參考那些大神的思路總會讓我有一些感慨。世界之大,山外有山,天外有天呀。總會有新奇的方法來解決,只有不斷的更新不斷的發現,在慢慢迭代的過程中找到一個更好的解決問題的模型,這個不僅需要想法,感覺積累和經驗也是非常重要的,好了,不嘚吧這麼多了,經驗總結到這裏,希望看到的盆友們能夠有所收穫。

斯是陋室惟“汝”德馨!歡迎關注和交流。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章