leetcode-287-寻找重复数
方法一: 二分法 O(nlogn) O(1)
class Solution { public int findDuplicate(int[] nums) { int len = nums.length; int left = 1; int right = len - 1; while(left < right){ int mid = (left + right) >>> 1; int cnt = 0; for(int num: nums){ if(num <= mid){ cnt += 1; } } if(cnt > mid){ right = mid; }else{ left = mid + 1; } } return left; } }
方法二:位运算 O(nlogn) O(1)
class Solution { public int findDuplicate(int[] nums) { int n = nums.length,ans = 0; int bit_max = 31; while(((n - 1) >> bit_max) == 0) { bit_max -= 1; } for (int bit = 0; bit <= bit_max; ++bit){ int x = 0, y = 0; for (int i = 0; i < n; ++i){ if ((nums[i] & (1 << bit)) != 0) { x += 1; } if (i >= 1 && ((i & (1 << bit)) != 0)) { y += 1; } } if (x > y){ ans |= 1 << bit; } } return ans; } }
方法三:快慢指针 O(n) O(1)
class Solution { public int findDuplicate(int[] nums) { int slow = 0, fast = 0; do { slow = nums[slow]; fast = nums[nums[fast]]; }while(slow != fast); slow = 0; while (slow != fast){ slow = nums[slow]; fast = nums[fast]; } return slow; } }