leetcode 287. 寻找重复数

给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

 

题解:

1.长度 n + 1 的整数数组

2.数值在1~n

3.至少存在一个重复的整数

4.只有一个数值重复,返回该数

5.不能更改原数组;可能不止重复出现一次

6.额外的 O(1) 空间;时间复杂度小于 O(n^2)

 

示例 1:

输入: [1,3,4,2,2]

输出: 2

示例 2:

输入: [3,1,3,4,2]

输出: 3

 

解题思路:二分查找

  • 如果不限制条件,题目简单解法还是很多的,比如哈希法,二分查找

  • 注意这n+1个数的取值在1~n之间,然后有一个或多个相同的重复元素,这样可以直接用数值来比较了

  • 直接用到二分查找框架中,左右端设指针相向移动,需要找到二分判定条件

  • 判定条件可以根据这n+1个数取值1~n的特点

  • 统计双指针中数,如果小于中数的个数比中数大,则在小于中数的那部分[left, mid]有重复元素;相反地,就在[mid+1, right]那部分

  • 直到左右指针相向移动到相同位置,即寻找元素

C/C++题解:

 

class Solution {

    public int findDuplicate(int[] nums) {

        int len = nums.size();

        int left = 1;

        int right = len - 1;

        while (left < right) { //直接拿值作比较

            int mid = (left + right)/2;

            int cnt = 0;

            for (int num : nums) { //统计小于中值的个数

                if (num <= mid) {

                    cnt += 1;}}

            if (cnt > mid) {// 如果小于中值的个数比中值大

                right = mid;// 重复元素位于区间 [left, mid]

            } else {// 否则重复元素位于区间[mid + 1, right]

                left = mid + 1;}}

        return left; }} //最后左右指针共同指向重复元素

Debug结果:

Java题解:

class Solution {

    public int findDuplicate(int[] nums) {

        int len = nums.length;

        int left = 1;

        int right = len - 1;

        while (left < right) { //直接拿值作比较

            int mid = (left + right)/2;

            int cnt = 0;

            for (int num : nums) { //统计小于中值的个数

                if (num <= mid) {

                    cnt += 1;}}

            if (cnt > mid) {// 如果小于中值的个数比中值大

                right = mid;// 重复元素位于区间 [left, mid]

            } else {// 否则重复元素位于区间[mid + 1, right]

                left = mid + 1;}}

        return left; }} //最后左右指针共同指向重复元素

 

Debug结果:

Python题解:

class Solution(object):

    def findDuplicate(self, nums):

        """ :type nums: List[int] :rtype: int"""

 

 

        # 数值从1~n,外加一个或多个范围内相同整数=n+1个

        n = len(nums)

        left = 1

        right = n - 1

        while  left < right: #直接拿值作比较

            mid = (left + right)/2

            cnt = 0

            for num in nums: #统计小于中值的个数

                if num <= mid:

                    cnt += 1

            if cnt > mid: # 如果小于中值的个数比中值大

                right = mid# 重复元素位于区间 [left, mid]

            else: #否则重复元素位于区间[mid + 1, right]

                left = mid + 1

        return left#最后左右指针共同指向重复元素

Debug结果:

更多题解移步公众号免费获取

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值