[LeetCode] 287. 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 repeated number in nums, return this repeated number.
You must solve the problem without modifying the array nums and using 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?
寻找重复数。
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。
你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-the-duplicate-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路一 - 二分法
注意数组是无序的。当得到数组长度 len 和数组长度的一半 mid 之后,用 count 记录有多少个数小于等于中间数 mid。举个例子,如果数组长度是 10,mid 则是 5,这里 mid 指的是数组长度的一半。如果小于 mid 的个数大于数组的一半,说明重复的数字一定是小于 mid 的;反之如果大于 mid 的个数过半,重复的数字一定是大于 mid 的。用二分法逐渐逼近这个值,注意 return 的是 left。
复杂度
时间O(nlogn) - 二分 logn * 每次找到 mid 之后要再把所有元素看一遍
空间O(1)
代码
Java实现
1 |
|
JavaScript实现
1 |
|
思路二 - 快慢指针
这个思路很难想到,参考 142 题。因为数组一定是有重复数字出现而且数字的范围不大于数组的长度,所以可以用快慢指针的思路做。当快慢指针相遇之后,再走第二遍,再次相遇的地方就是环的起点,也就是重复的数字。
复杂度
时间O(n)
空间O(1)
代码
Java实现
1 |
|
JavaScript实现
1 |
|