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

浙公网安备 33010602011771号