您的位置:首页 > 其它

Leetcode - 287. Find the Duplicate Number

2016-03-05 09:03 363 查看
Problem Description:

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.

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.

Analysis :

1. Binary Search O(nlogn) solution

Find the mid in the integer range, traverse the nums count the digit not greater than the mid.

if (count <= mid) the dups digit occurs in the right half;

else the dups in the left half.

int findDuplicate(vector<int>& nums) {
int n = nums.size();
int l = 0, r = n - 1;
while (l < r)
{
int m = l + ((r - l) >> 1);
int count = 0;
for (int i = 0; i < n; ++i)
{
if (nums[i] <= m)
count ++;
}
if (count <= m )
l = m + 1;
else r = m;
}
return l;
}```

2. Floyd's loop detection;
if the size of  nums is n;
so the index  range from [0...n - 1], the digit  [1...n - 1];
We can define a function from the set {0,...n - 1} onto itself.
f(i) = A [i];
so the duplicated value corresponds to a pair of indices i != j, such that f(i)
= f(j), Our challenge ,therefore, is to find the pair(i, j).
because the f(0) != 0,it can't be in the cycle, so we can start from nums[0].
if we want to start from the end f(n - 1) might equal with n - 1, so we set the
f(n) = A
- 1;
Start from the 0;
```
int findDuplicate(vector<int>& nums)
{
int n = nums.size();
if(n <= 1) return -1;
int slow = nums[0], fast = nums[nums[0]];
while (slow != fast)
{
slow = nums[slow];
fast = nums[nums[fast]];
}
fast = 0;
while (fast != slow)
{
fast = nums[fast];
slow = nums[slow];
}
return slow;
}


Start from the end;

int findDuplicate(vector<int>& nums) {
int n = nums.size(), slow = n - 1, fast = n - 1;
do {
slow = nums[slow] - 1;
fast = nums[nums[fast] - 1] - 1;
} while (slow != fast);
fast = n - 1;
do {
slow = nums[slow] - 1;
fast = nums[fast] - 1;
} while (slow != fast);
return slow + 1;
}


Another tricky solution using O(1) space, Here is the Link

int findDuplicate(vector<int>& nums)
{
int n = -1;
for(int i = 0; i < nums.size(); i++) {
n = abs(nums[i]);
if(nums
< 0) {
break;
}
else {
nums
*= -1;
}
}
// for(int j = 0; j < nums.size(); j++) {
//     nums[j] = std::abs(nums[j]);
// }
return n;
}


4.

We can count the sum of each 32 bits separately for the given array (stored in “b” variable) and for the array [1, 2, 3, …, n] (stored in “a” variable). If “b” is greater than “a”, it means that duplicated number has 1 at the current bit position (otherwise, “b” couldn’t be greater than “a”).

int findDuplicate(vector<int>& nums)
{
int n = nums.size() - 1, res = 0;
for (int p = 0; p < 32; ++p)
{
int bit = (1 << p), a = 0, b = 0;
for (int i = 0; i <= n; ++i)
{
if (i > 0 && (i & bit) > 0) ++a;
if ((nums[i] & bit) > 0) ++b;
}
if (b > a) res += bit;
}
return res;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: