[leetcode] 287. Find the Duplicate Number 寻找重复数

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.

Example 1:

Input: [1,3,4,2,2]
Output: 2

Example 2:

Input: [3,1,3,4,2]
Output: 3

Note:

  1. You must not modify the array (assume the array is read only).
  2. You must use only constant, O(1) extra space.
  3. Your runtime complexity should be less than O(n2).
  4. There is only one duplicate number in the array, but it could be repeated more than once.

分析

题目的意思是:给定一个数组,找出其中的一个重复的数。

  • 我们在区别[1, n]中搜索,首先求出中点mid,然后遍历整个数组,统计所有小于等于mid的数的个数,如果个数大于mid,则说明重复值在[mid+1, n]之间,反之,重复值应在[1, mid-1]之间,然后依次类推,直到搜索完成,此时的low就是我们要求的重复值。

C++ 实现

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int low=1;
        int high=nums.size()-1;
        while(low<high){
            int mid=(low+high)/2;
            int count=0;
            for(auto num:nums){
                if(num<=mid){
                    count++;
                } 
            }
            if(count<=mid){
                low=mid+1;
            }else{
                high=mid;
            }
        }
        return low;
    }
};

Python实现

注意,这里的二分,low和high指的是重复的数字,不是数组的index,理解这一点就容易了。

class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        low = 1
        high = len(nums)-1
        while low<high:
            mid = (low+high)>>1
            cnt=0
            for num in nums:
                if num<=mid:
                    cnt+=1

            if mid>=cnt:
                low=mid+1
            else:
                high = mid
        return low

下面是一个快慢指针的写法,思路很新颖:

class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        slow = nums[0]
        fast = nums[0]
        while True:
            slow = nums[slow]
            fast = nums[nums[fast]]
            if slow == fast:
                break

        p1 = nums[0]
        p2 = slow
        while p1!=p2:
            p1 = nums[p1]
            p2 = nums[p2]
        return p1

参考文献

[LeetCode] Find the Duplicate Number 寻找重复数

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值