Given an array of integers nums
containing n + 1
integers where each integer is in the range [1, n]
inclusive.
There is only one repeated number in nums
, return this repeated number.
You must solve the problem without modifying the array nums
and uses only constant extra space.
Example 1:
Input: nums = [1,3,4,2,2] Output: 2
Example 2:
Input: nums = [3,1,3,4,2] Output: 3
Constraints:
1 <= n <= 105
nums.length == n + 1
1 <= nums[i] <= n
- All the integers in
nums
appear only once except for precisely one integer which appears two or more times.
Follow up:
- How can we prove that at least one duplicate number must exist in
nums
? - Can you solve the problem in linear runtime complexity?
We can observe that if the number of elements in
Therefore, we can use binary search to find
The time complexity is
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
def f(x: int) -> bool:
return sum(v <= x for v in nums) > x
return bisect_left(range(len(nums)), True, key=f)
class Solution {
public int findDuplicate(int[] nums) {
int l = 0, r = nums.length - 1;
while (l < r) {
int mid = (l + r) >> 1;
int cnt = 0;
for (int v : nums) {
if (v <= mid) {
++cnt;
}
}
if (cnt > mid) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
}
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
while (l < r) {
int mid = (l + r) >> 1;
int cnt = 0;
for (int& v : nums) {
cnt += v <= mid;
}
if (cnt > mid) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
};
func findDuplicate(nums []int) int {
return sort.Search(len(nums), func(x int) bool {
cnt := 0
for _, v := range nums {
if v <= x {
cnt++
}
}
return cnt > x
})
}
function findDuplicate(nums: number[]): number {
let l = 0;
let r = nums.length - 1;
while (l < r) {
const mid = (l + r) >> 1;
let cnt = 0;
for (const v of nums) {
if (v <= mid) {
++cnt;
}
}
if (cnt > mid) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
impl Solution {
#[allow(dead_code)]
pub fn find_duplicate(nums: Vec<i32>) -> i32 {
let mut left = 0;
let mut right = nums.len() - 1;
while left < right {
let mid = (left + right) >> 1;
let cnt = nums
.iter()
.filter(|x| **x <= (mid as i32))
.count();
if cnt > mid {
right = mid;
} else {
left = mid + 1;
}
}
left as i32
}
}
/**
* @param {number[]} nums
* @return {number}
*/
var findDuplicate = function (nums) {
let l = 0;
let r = nums.length - 1;
while (l < r) {
const mid = (l + r) >> 1;
let cnt = 0;
for (const v of nums) {
if (v <= mid) {
++cnt;
}
}
if (cnt > mid) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
};