Leetcode 287. 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.
解法1:sort
将数组先进行排序,因为一样的元素至少有两个,所以只需将相邻两元素比较即可,此方法时间复杂度符合要求,空间复杂度不符合要求,因为题意中是不能改变原数组的,所以需要额外的copy一个原数组
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums.sort()
for i in range(1,len(nums)):
if nums[i] == nums[i-1]:
return nums[i]
时间复杂度:O(NlogN)
空间复杂度:O(N)
解法2:利用set
利用集合的方法时间复杂度符合要求,但是空间复杂度不符合
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
memo = set()
for i in range(len(nums)):
if nums[i] in memo:
return nums[i]
memo.add(nums[i])
时间复杂度:O(N)
空间复杂度:O(N)
解法3:Floyd’s Tortoise and Hare (Cycle Detection)
实际上这题与142本质上是相同的,因为数组大小为n,而元素的大小也不超过n,所以实际上每个位置的元素值相当于指向下一个位置的指针,就可以采用Floyd的双指针法,关于这种方法的详细解释,参考我对142的解析
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
#phase 1
tortoise = nums[0]
hare = nums[0]
while True:
tortoise = nums[tortoise]
hare = nums[nums[hare]]
if tortoise == hare:
break
#phase 2
ptr1 = nums[0]
ptr2 = tortoise
while ptr1 != ptr2:
ptr1 = nums[ptr1]
ptr2 = nums[ptr2]
return ptr1
时间复杂度:O(N)
空间复杂度:O(1)
C++本版
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int slow = nums[0], fast = nums[0];
// get the intersection
while(true){
slow = nums[slow];
fast = nums[nums[fast]];
if(slow == fast) break;
}
slow = nums[0];
while(slow != fast){
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
};