返回介绍

solution / 0200-0299 / 0287.Find the Duplicate Number / README_EN

发布于 2024-06-17 01:04:02 字数 5237 浏览 0 评论 0 收藏 0

287. Find the Duplicate Number

中文文档

Description

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

Example 3:

Input: nums = [3,3,3,3,3]
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?

Solutions

Solution 1: Binary Search

We can observe that if the number of elements in $[1,..x]$ is greater than $x$, then the duplicate number must be in $[1,..x]$, otherwise the duplicate number must be in $[x+1,..n]$.

Therefore, we can use binary search to find $x$, and check whether the number of elements in $[1,..x]$ is greater than $x$ at each iteration. This way, we can determine which interval the duplicate number is in, and narrow down the search range until we find the duplicate number.

The time complexity is $O(n \times \log n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$.

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;
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文