题目
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,
extra space.
Your runtime complexity should be less than
.
There is only one duplicate number in the array, but it could be repeated more than once.
题意
给定一个含有
个元素的数组,里面的每个元素都属于
,里面有且只有一个元素会出现多次,把它找出来。
要求空间复杂度
,时间复杂度小于
时间复杂度 的解法
在整个数组的最大值和最小值之间,二分寻找答案。
首先,扫描一遍数组,找到最大值l,最小值r。如果中途发现最大值或最小值出现了多次,则直接输出结果。
然后计算 mid ,统计这个数组中比mid小的数字的个数less,以及mid自己出现的次数equal。
如果equal超过1,说明mid出现了多次,直接输出结果。
否则看 less有没有超过目标对象数字个数的一半,如果有说明重复元素在小于Mid,否则重复的元素大于mid。
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int n = nums.size();
int l = nums[0];
int lc = 0;
int r = nums[0];
int lr = 0;
for (int i = 1; i < n; i++)
{
if (nums[i] < l)
{
l = nums[i];
}
else if (nums[i] == l)
{
return l;
}
if (nums[i]>r)
{
r = nums[i];
}
else if (nums[i]==r)
{
return r;
}
}
while (l<=r)
{
int mid = (l + r) / 2;
int less = 0;
int equal = 0;
for (int i = 0; i < n; i++)
{
if (nums[i] < mid) less++;
else if (nums[i] == mid) equal++;
if (equal > 1) return mid;
}
if (less < mid)
{
l = mid + 1;
}
else
{
r = mid - 1;
}
}
return l;
}
};