一、题目
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。
假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。
你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。
示例 1:
输入:nums = [1,3,4,2,2]
输出:2
示例 2:
输入:nums = [3,1,3,4,2]
输出:3
作者:力扣 (LeetCode) 链接:leetcode.cn/leetbook/re… 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
二、思考
暴力解法
- collections.Counter() 提供计数器工具以支持方便和快速的计数
- 如果存在重复的整数,就通过for循环加1
- 因此就得到了一个技术的字典,通过循环这个字典,value大于1的值就是要的参数
- 这里使用推导式得出结果
二分查找
- 首先定义左右区间,leftIndex, rightIndex,中间值mid, 最终结果ans
- 通过循环,判断中间值的与大于中间值的数量
- 如果大于中间值,说明当前区间应该向左移动
- 如果小于中间值,那么说明右区间应该向左移动,同时得到的中间值就是返回值
三、代码
暴力解法
nums = [1,3,4,2,2]
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
"""
collections.Counter() 提供计数器工具以支持方便和快速的计数
如果存在重复的整数,就通过for循环加1
因此就得到了一个技术的字典,通过循环这个字典,value大于1的值就是要的参数
这里使用推导式得出结果
:param nums:
:return:
"""
m = collections.Counter()
for num in nums:
m[num] += 1
return [k for k, v in m.items() if v > 1][0]
Solution().findDuplicate(nums)
二分查找
nums = [3,1,3,4,2]
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
"""
二分查找
首先定义左右区间,leftIndex, rightIndex,中间值mid, 最终结果ans
通过循环,判断中间值的与大于中间值的数量
如果大于中间值,说明当前区间应该向左移动
如果小于中间值,那么说明右区间应该向左移动,同时得到的中间值就是返回值
处理
:param nums:
:return:
"""
len1, leftIndex, rightIndex, ans = len(nums), 1, len(nums) - 1, -1
while leftIndex <= rightIndex:
mid = (leftIndex + rightIndex) // 2
cnt = 0
for i in nums:
cnt += i <= mid
if cnt <= mid:
leftIndex = mid + 1
else:
rightIndex = mid - 1
ans = mid
print(ans)
return ans
Solution().findDuplicate(nums)