【LeetCode】287. Find the Duplicate Number 寻找重复数(Medium)(JAVA)
题目地址: https://leetcode.com/problems/find-the-duplicate-number/
题目描述:
Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive.
There is only one duplicate number in nums, return this duplicate number.
Follow-ups:
- How can we prove that at least one duplicate number must exist in nums?
- Can you solve the problem without modifying the array nums?
- Can you solve the problem using only constant, O(1) extra space?
- Can you solve the problem with runtime complexity less than O(n^2)?
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 = [1,1]
Output: 1
Example 4:
Input: nums = [1,1,2]
Output: 1
Constraints:
- 2 <= n <= 3 * 10^4
- 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.
题目大意
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
说明:
- 不能更改原数组(假设数组是只读的)。
- 只能使用额外的 O(1) 的空间。
- 时间复杂度小于 O(n^2) 。
- 数组中只有一个重复的数字,但它可能不止重复出现一次。
解题方法
- 这道题找的是重复的元素,而且仅存在一个重复的元素(重复出现的次数 >= 2),
- 如果按照 i -> nums[i] -> nums[nums[i]] 连接起来 (i 从 0 开始,nums[i] != 0),存在重复元素,肯定就会形成一个环
- 这一道问题就变成了找出环的入口节点的问题
- 可用快慢指针的来解决
class Solution {
public int findDuplicate(int[] nums) {
int fast = nums[nums[0]];
int slow = nums[0];
while (fast != slow) {
fast = nums[nums[fast]];
slow = nums[slow];
}
fast = 0;
while (fast != slow) {
fast = nums[fast];
slow = nums[slow];
}
return slow;
}
}
执行耗时:0 ms,击败了100.00% 的Java用户
内存消耗:38.5 MB,击败了65.28% 的Java用户
![](https://i-blog.csdnimg.cn/blog_migrate/6c56d31f951aece27c5faae608dfac2e.jpeg#pic_center)