Leetcode刷题java之287. 寻找重复数

本文探讨了两种在数组中寻找唯一重复元素的方法:一种是使用二分查找,通过计数小于等于中间值的元素来定位重复区间;另一种是利用快慢指针形成环,找到环的入口即为重复数字。两种策略在解决LeetCode问题Find the Duplicate Number中有经典应用。
摘要由CSDN通过智能技术生成

题目

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

假设 nums 只有 一个重复的整数 ,找出 这个重复的数 。

思路1

二分法
计算数组中小于等于mid的值(cnt)有多少个,若cnt<=mid值,则代表重复的值在mid的右侧;若cnt>mid值,则代表重复的值在mid的左侧;

代码1

class Solution {
    public int findDuplicate(int[] nums) {
        int n = nums.length;
        int l = 0;
        int r = n - 1;
        int ans = 0;
        while (l <= r) {
            int mid = (l + r) >> 1;
            int cnt = 0;
            for(int i = 0;i < n;++i) {
                if (nums[i] <= mid) {
                    cnt++;
                }
            }
            if (cnt <= mid) {
                l = mid + 1;
            } else {
                r = mid - 1;
                ans = mid;
            }
        }
        return ans;
        
    }
}```
## 思路2
快慢指针
在数组中建立环:即通过数组的值作为索引来指向下一个数组的值;即对于数组[1,2,3,4,5,6,7,3],通过1->2->3->4->5->6->7->3->4->5->6->7->3->4->5->6->7。。。(环为3->4->5->6->7->3)。我们想要找的重复的值就是环的入口3。
首先通过设定快慢指针fast与slow为0。slow每次移动一步(slow=nums[slow]),fast每次移动两步fast=nums[nums[fast]],这样它们会在环中相遇(因为环外不可能相遇,在环中循环时会相遇),记录相遇的位置。
再设置finder=0,使finder和slow同时移动,相遇时即为重复的值,即环的入口。[详细原因见链接内容。](https://leetcode-cn.com/problems/find-the-duplicate-number/solution/kuai-man-zhi-zhen-de-jie-shi-cong-damien_undoxie-d/)
## 代码2

```java
class Solution {
    public int findDuplicate(int[] nums) {
        int slow = 0;
        int fast = 0;
        do {
            slow = nums[slow];
            fast = nums[nums[fast]];
        } while (slow != fast);
        int finder = 0;
        do {
            finder = nums[finder];
            slow = nums[slow];
        } while (finder != slow);
        return slow;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值