關注「鬆寶寫代碼」,精選好文,每日一題node
時間永遠是本身的面試
每分每秒也都是爲本身的未來鋪墊和增值算法
通過三天時間,已經有小夥伴(xpf666)給咱們貢獻文章了,超級開心和激動,由於咱們不是一我的在戰鬥,
不是一我的在努力提升本身,加入咱們,數組
如何加入咱們?學習
第一步:文章下面留言,留言內容:想寫什麼文章。spa
第二步:咱們就會找到你3d
做者:xpf666來源:原創指針
2020.12.23 日剛立的 flag,每日一題,題目類型不限制,能夠是:算法題,面試題,闡述題等等。code
本文是「每日一題」第 4 題,由 xpf666 帶來的文章:如何科學高效的尋找重複元素?blog
往期「每日一題」:
https://mp.weixin.qq.com/s/Qu...
https://mp.weixin.qq.com/s/om...
https://mp.weixin.qq.com/s/O8...
給定一個長度爲 n 的數組 nums,判斷是否有重複值。
示例:輸入[1,2,3,2,1,4,5] 輸出 1 或 2
思路:根據經驗,基本上全部判斷重複的需求,均可以經過 Set 或者 Map 解決,Set 解決方式就是判斷 add 方法的返回是 true 仍是 false,false 就證實以前已存在,也就是數據重複。Map 是經過 containsKey,true 就說明以前存在 key。
題解:
public int getResult(int[] nums) { Set<Integer> set = new HashSet<Integer>(); int result = -1; for (int num : nums) { if (!set.add(num)) { result = num; break; } } return result; }
若是上面代碼格式出現問題,能夠查看下面代碼圖片
遍歷 n 次而且 Set 內容最可能是 n 個字符,複雜度都是 O(n)
給定一個長度爲 n 的數組 nums,判斷是否有重複值,而且兩個重複值距離不超過 k。
示例:輸入[1,2,3,2,1,4,5] ,k = 2 輸出 true(兩個 2)
思路:同問題一,只要多判斷一次 Set 長度便可。
題解:
public boolean containsNearbyDuplicate(int[] nums, int k) { Set<Integer> set = new HashSet<Integer>(); boolean result = false; for (int i = 0; i < nums.length; i++) { if (!set.add(nums[i])) { result = true; break; } if (set.size() > k) { // 超過長度就刪除最遠的一個數 set.remove(nums[i-k]); } } return result; }
若是上面代碼格式出現問題,能夠查看下面代碼圖片
遍歷 n 次而且 k 最多 n 個字符,複雜度都是 O(n)
給定一個包含 n + 1 個整數的數組 nums,其數字都在 1 到 n 之間(包括 1 和
n),只有一個重複的整數,找出這個重複的數字。
示例:輸入[1,3,4,2,2] 輸出 2
思路:可經過問題 1 方式解決。還能夠經過快慢指針法解決:將數組當作一個鏈表,下標爲當前指針(node),值指向下一指針(nextNode),數組出現重複的數字意味着有兩個指針的 nextNode 相同。而後經過快慢指針法解決。
題解:
public int getResult(int[] nums) { int result = 0; int slow = 0, fast = 0; do { slow = nums[slow]; fast = nums[nums[fast]]; } while (slow != fast); do { slow = nums[slow]; result = nums[result]; } while (result != slow); return result; }
若是上面代碼格式出現問題,能夠查看下面代碼圖片
遍歷 2n 次時間複雜的是 O(n),只用了常量個字符,空間複雜度是 O(1)
給定一個數組
nums,除了某個元素只出現一次之外,其他每一個元素均出現兩次。找出那個只出現了一次的元素。
示例:輸入[1,1,4,2,2] 輸出 4
思路:可經過問題 1 方式解決。還能夠經過位運算解決,兩個相同數異或後爲 0,數組全部元素執行一次異或操做,剩下就是出現一次的數。
題解:
public int getResult(int[] nums) { int result = 0; for (int num : nums) { result = result ^ num; } return result; }
若是上面代碼格式出現問題,能夠查看下面代碼圖片
遍歷 n 次時間複雜的是 O(n),只用了常量個字符,空間複雜度是 O(1)
給定一個數組
nums,除了兩個元素只出現一次之外,其他每一個元素均出現兩次。找出那個只出現了一次的元素。
示例:輸入[1,1,3,4,2,2] 輸出[3,4]
思路:可經過問題 1 方式解決。還能夠經過位運算解決,和題 4 區別是存在 2 個只出現一次的數,因此要想辦法把這兩個數區分出來。先將數組全部元素異或,得出的值是兩個只出現一次元素 a,b 的異或值 numsXOR(如 10010)。numsXOR 二進制中 1 的位就是 a 和 b 差別位(由於不一樣的值異或纔是 1),如今只須要找 lowbit(最右一位差別值,10),而後經過 lowbit 和 a
, b
進行與運算(&),得出的值就必定不一樣,這樣能夠分出 a 和 b,最後按照異或運算就能得出結果(其餘重複的不用管,無論分到哪一組,重複的數異或都是 0)
題解:
public int[] singleNumber(int[] nums) { int[] results = new int[]{0,0}; int numsXOR = 0; // 兩個數異或值 for (int num : nums) { numsXOR = numsXOR ^ num; } int lowBit = numsXOR & (-numsXOR); // lowbit值,用於區分a和b for (int num : nums) { if ((lowBit & num) == 0) { results[0] = results[0] ^ num; } else { results[1] = results[1] ^ num; } } return results; }
若是上面代碼格式出現問題,能夠查看下面代碼圖片
遍歷 2n 次時間複雜的是 O(n),只用了常量個字符,空間複雜度是 O(1)
「鬆寶寫代碼」公衆號:開發知識體系構建,技術分享,項目實戰,實驗室,每日一題,帶你一塊兒學習新技術,總結學習過程,讓你進階到高級資深工程師,學習項目管理,思考職業發展,生活感悟,充實中成長起來。問題或建議,請公衆號留言。
回覆「校招」獲取內推碼
回覆「社招」獲取內推
回覆「實習生」獲取內推
後續會有更多福利
回覆「算法」獲取算法學習資料
https://mp.weixin.qq.com/s/Qu...