LeetCode 287. Find the Duplicate Number
原题链接在这里:https://leetcode.com/problems/find-the-duplicate-number/
题目:
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Example 1:
Input: [1,3,4,2,2]
Output: 2
Example 2:
Input: [3,1,3,4,2] Output: 3
Note:
- You must not modify the array (assume the array is read only).
- You must use only constant, O(1) extra space.
- Your runtime complexity should be less than O(n2).
- There is only one duplicate number in the array, but it could be repeated more than once.
题解:
每次取 Math.abs(nums[i])为index, 然后跳到index上,如果这个数是正数,那么把它变成负数,如果是负数,说明之前已经有操作使其为负,就有重复,返回index. 有类似题目Find All Numbers Disappeared in an Array.
Time Complexity: O(n). Space: O(1).
AC Java:
1 public class Solution { 2 public int findDuplicate(int[] nums) { 3 if(nums == null || nums.length == 0){ 4 throw new IllegalArgumentException("Invalid input array."); 5 } 6 7 for(int i = 0; i<nums.length; i++){ 8 int index = Math.abs(nums[i]); 9 if(nums[index] > 0){ 10 nums[index] = -nums[index]; 11 }else{ 12 return index; 13 } 14 } 15 16 //出了loop还没有返回 那么说明是error 17 return -1; 18 } 19 }
也可以采用First Missing Positive中swap的方法,把nums[i] swap到 index = nums[i]的位置上.
第二遍扫描时如果出现了i != nums[i]时,就是nums[i]是duplicate.
Time Complexity: O(nums.length). Space: O(1).
AC Java:
1 class Solution { 2 public int findDuplicate(int[] nums) { 3 for(int i = 0; i<nums.length; i++){ 4 if(nums[i]>=0 && nums[i]<nums.length && nums[i]!=nums[nums[i]]){ 5 swap(nums, i, nums[i]); 6 i--; 7 } 8 } 9 10 for(int i = 0; i<nums.length; i++){ 11 if(nums[i] != i){ 12 return nums[i]; 13 } 14 } 15 16 return -1; 17 } 18 19 private void swap(int [] nums, int i, int j){ 20 int temp = nums[i]; 21 nums[i] = nums[j]; 22 nums[j] = temp; 23 } 24 }
居然能由此题联想到Linked List Cycle II也是厉害.
这里的duplicate number就是cycle的起点. 课通过快慢指针找到cycle的起点.
Note: 这里回置walker是回置到0. 而不是nums[0]. 因为接下来是跳动nums[runner], runner 是index.
Time Complexity: O(n). Space: O(1).
AC Java:
1 public class Solution { 2 public int findDuplicate(int[] nums) { 3 if(nums == null || nums.length == 0){ 4 throw new IllegalArgumentException("Invalid input array."); 5 } 6 7 //walker and runner can't start at the same point 8 //or while loop condition walker != runner is never used 9 //while loop is skipped. 10 int walker = nums[0]; 11 int runner = nums[nums[0]]; 12 while(walker != runner){ 13 walker = nums[walker]; 14 runner = nums[nums[runner]]; 15 } 16 17 walker = 0; 18 while(walker != runner){ 19 walker = nums[walker]; 20 runner = nums[runner]; 21 } 22 23 return walker; 24 } 25 }