給定一個範圍在 1 ≤ a[i] ≤ n ( n = 數組大小 ) 的 整型數組,數組中的元素一些出現了兩次,另外一些只出現一次。數組
找到全部在 [1, n] 範圍之間沒有出如今數組中的數字。網絡
您能在不使用額外空間且時間複雜度爲O(n)的狀況下完成這個任務嗎? 你能夠假定返回的數組不算在額外空間內。app
示例:優化
輸入:
[4,3,2,7,8,2,3,1]spa
輸出:
[5,6]code
來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。blog
找出數組中重複的數字。排序
在一個長度爲 n 的數組 nums 裏的全部數字都在 0~n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每一個數字重複了幾回。請找出數組中任意一個重複的數字。索引
示例 1:leetcode
輸入:
[2, 3, 1, 0, 2, 5, 3]
輸出:2 或 3
限制:
2 <= n <= 100000
來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。
兩個題其實想法是差很少的,就放到一塊兒來講了。
在不開闢新空間的狀況下,咱們要來達到題目要求,那麼咱們只能在原數組上進行操做。那如何在原數組上操做?並且還須要線性時間。
咱們知道數組元素的範圍必定是1~n 或者 0~ n-1,這樣就優化了排序的時間,普通的數組排序時間會消耗不少,但這個比較特殊,咱們讓每一個數迴歸到數組中與其對應的索引上,咱們就完成了所謂的排序,若是有不同的,那麼這個數一定不會和它的索引相對應,這樣咱們就找出了消失的數組,若是交換過程當中,目標即該數對應的索引的位置上已經對應了,那麼就說明這個數重複了,返回這個數就能夠了。
在這裏我只用這個解法作了第一個題。
1 vector<int> findDisappearedNumbers(vector<int>& nums) { 2 vector<int> v; 3 for(int i = 0; i < nums.size(); i++) { 4 while ((nums[i] != i + 1) && (nums[nums[i] - 1] != nums[i])) { 5 int t = nums[i]; 6 nums[i] = nums[t - 1]; 7 nums[t - 1] = t; 8 } 9 } 10 for(int i = 0; i < nums.size(); i++) { 11 if(nums[i] != i + 1) 12 v.push_back(i + 1); 13 } 14 return v; 15 }
這是官方題解,如下解法來源於這裏。
官方的解法巧妙地利用了求餘,也是在原數組上進行修改。
咱們根據求餘數求得該數對應的索引,讓該索引的值 +n,循環完畢後,沒出現的那個數對應的索引的值必定是小於n的,而大於等於2n的就是出現兩次或兩次以上的。
這裏我只寫了第二個題的解法
1 int findRepeatNumber(vector<int>& nums) { 2 int n = nums.size(); 3 for(int i = 0; i < n; i++) { 4 int x = nums[i] % n; 5 nums[x] += n; 6 } 7 for(int i = 0; i < n; i++) { 8 if(nums[i] >= 2 * n) 9 return i; 10 } 11 return -1; 12 }