1. 程式人生 > 實用技巧 >力扣 #287尋找重複數

力扣 #287尋找重複數

1 public int findDuplicate(int[] nums) {
2     Arrays.sort(nums);
3     for (int i = 0; i < nums.length - 1; i++) {
4         if (nums[i] == nums[i + 1]) {
5             return nums[i];
6         }
7     }
8     return -1;
9 }

方法一 排序後對比後一個 沒技術含量 不解釋了

 1 class Solution {
 2     public int findDuplicate(int
[] nums) { 3 Set<Integer> set = new HashSet<>(); 4 for(int i = 0; i < nums.length; i++){ 5 if(set.contains(nums[i])){ 6 return nums[i]; 7 } 8 set.add(nums[i]); 9 } 10 return 0; 11 } 12 }

方法二 HashSet 時間複雜度應該是O(N)吧

 1 class Solution {
 2     public int findDuplicate(int[] nums) {
 3         int n = nums.length - 1;
 4         int low = 1;
 5         int high = n;
 6         while (low < high) {
 7             int mid = (low + high) >>> 1;
 8             int count = 0;
 9             for (int i = 0; i < nums.length; i++) {
10 if (nums[i] <= mid) { 11 count++; 12 } 13 } 14 if (count > mid) { 15 high = mid; 16 } else { 17 low = mid + 1; 18 } 19 } 20 return low; 21 } 22 }

進階的二分查找了 例子:[2, 4, 5, 2, 3, 1, 6, 7] 時間複雜度O(NlogN)

第一次查詢count = 5 mid = 4 count > mid 說明 數字[1, 2, 3, 4]中有一個出現重複了 縮小搜尋區間 high = mid

第二次查詢count = 3 mid = 2 count > mid 說明 數字[1, 2]中有一個出現重複了 繼續縮小區間 high = mid

第三次查詢 count = 1 mid = 1 說明區間[1]沒有重複 low = mid + 1 = high 跳出

關鍵在於為什麼 是left < right 跳出而不是之前所說的left <= right

left < right表示在退出迴圈的時候 區間裡只有 1 個數 這個數有可能就是我們要找的數 left <= right表示在區間裡只剩下一個數的時候 還需要繼續查詢