力扣 #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 表示在区间里只剩下一个数的时候 还需要继续查找

posted @ 2020-12-03 20:37  加利亚的赤色恶魔  阅读(97)  评论(0)    收藏  举报