日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Leedcode][JAVA][第287题][寻找重复数][HashSet][二分查找][快慢指针]

發布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leedcode][JAVA][第287题][寻找重复数][HashSet][二分查找][快慢指针] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【問題描述】[中等]

給定一個包含 n + 1 個整數的數組 nums,其數字都在 1 到 n 之間(包括 1 和 n),可知至少存在一個重復的整數。假設只有一個重復的整數,找出這個重復的數。輸入: [1,3,4,2,2] 輸出: 2說明:不能更改原數組(假設數組是只讀的)。 只能使用額外的 O(1) 的空間。 時間復雜度小于 O(n2) 。 數組中只有一個重復的數字,但它可能不止重復出現一次。來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/find-the-duplicate-number 著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。

【解答思路】

1. 排序法(不符合題意)

時間復雜度:O(N) 空間復雜度:O(1)

public int findDuplicate(int[] nums) {Arrays.sort(nums);for (int i = 0; i < nums.length - 1; i++) {if (nums[i] == nums[i + 1]) {return nums[i];}}return -1; }
2. HashSet (不符合題意)

時間復雜度:O(N) 空間復雜度:O(N)

public int findDuplicate(int[] nums) {HashSet<Integer> set = new HashSet<>();for (int i = 0; i <= nums.length - 1; i++) {if (set.contains(nums[i])) {return nums[i];}else{set.add(nums[i]);}}return -1; }
3.二分查找(符合題意)



時間復雜度:O(NlogN) 空間復雜度:O(1)

public class Solution {public int findDuplicate(int[] nums) {int len = nums.length;int left = 1;int right = len - 1;while (left < right) {// 在 Java 里可以這么用,當 left + right 溢出的時候,無符號右移保證結果依然正確int mid = (left + right) >>> 1;int cnt = 0;for (int num : nums) {if (num <= mid) {cnt += 1;}}// 根據抽屜原理,小于等于 4 的個數如果嚴格大于 4 個// 此時重復元素一定出現在 [1, 4] 區間里if (cnt > mid) {// 重復元素位于區間 [left, mid]right = mid;} else {// if 分析正確了以后,else 搜索的區間就是 if 的反面// [mid + 1, right]left = mid + 1;}}return left;} }
4. 雙指針(技巧型 符合體題意)





時間復雜度:O(N) 空間復雜度:O(1)

public int findDuplicate(int[] nums) {int slow = nums[0];int fast = nums[nums[0]];//尋找相遇點while (slow != fast) {slow = nums[slow];fast = nums[nums[fast]];}//slow 從起點出發, fast 從相遇點出發, 一次走一步slow = 0;while (slow != fast) {slow = nums[slow];fast = nums[fast];}return slow; }
5.二進制(不一定符合題意)

比較1到n和nums各位二進制“1”的數量,nums多出來的1的組合就是重復數組


時間復雜度:O(N) 空間復雜度:O(1)

public int findDuplicate(int[] nums) {int res = 0;int n = nums.length; //統計每一列 1 的個數for (int i = 0; i < 32; i++) {int a = 0;int b = 0;int mask = (1 << i);for (int j = 0; j < n; j++) {//統計原數組當前列 1 的個數if ((nums[j] & mask) > 0) {a++;}//統計 1 到 n 序列中當前列 1 的個數if ((j & mask) > 0) {b++;}}if (a > b) {res = res | mask;}}return res; }

【總結】

1.二分法查找有序數組 還可以用于確定一個有范圍的整數
2.二分查找經驗(先搞懂思路,再研究細節,多做問題去應用)
  • 把定義區間成為左閉右閉區間,左右邊界是無差別的,弄成左閉右開,反而增加了思考的復雜程度;
  • 明確 int = left + ( right - left ) / 2 這里除以 2 是下取整;
  • 明確 while(left <= right) 和 while(left < right) 這兩種寫法其實在思路上有本質差別, while(left <= right) 在循環體內部直接查找元素,而 while(left < right) 在循環體內部一直在排除元素,第 2 種思路在解決復雜問題的時候,可以使得問題變得簡單;
  • 始終在思考下一輪搜索區間是什么,把它作為注釋寫到代碼里面,就能幫助我們搞清楚邊界是不是能取到,等于、+1 、-1 之類的細節;
  • 思考清楚每一行代碼背后的語義是什么,保證語義上清晰,也是寫對代碼,減少 bug 的一個非常有效的策略。
3. 快慢指針 鏈表 數組(特定條件)

轉載鏈接:https://leetcode-cn.com/problems/find-the-duplicate-number/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–52/

參考鏈接:https://leetcode-cn.com/problems/find-the-duplicate-number/solution/er-fen-fa-si-lu-ji-dai-ma-python-by-liweiwei1419/

快慢指針動畫參考鏈接:https://leetcode-cn.com/problems/find-the-duplicate-number/solution/xun-zhao-zhong-fu-shu-by-leetcode-solution/

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的[Leedcode][JAVA][第287题][寻找重复数][HashSet][二分查找][快慢指针]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。