概述
本题同样让我们找数组中重复的数字,但是给出了很多限制条件。其实leetcode好像对一些限制条件,无法做出判断,我们还是自我严格要求的好哦!
首先,第一个不可以改变数组,其实这个就是限制了我们排序,如果排序,然后再遍历一下很快就能找到重复的数字了,时间复杂度O(nlogn),空间复杂度O(1);
其次,空间复杂度O(1),这个限制了我们使用hash查找,因为hash时间复杂度是O(1),但是空间要O(n);
其次,时间复杂度小于O(n^2),这个限制了我们暴力求解,循环两次也可以得到结果,但是时间复杂度需要O(n^2);
最后,它说数组里重复的数字可能重复不止两次,这个限制了我们使用数学方法,也就是如果只有一个数重复了两次,我们可以等差求和,然后相减就可以得到结果了。
然后,我们回头看这四种解法,明显是第三种存在可以优化的地方,n^2可以降低到nlogn,一般使用的就是二分法了。找到中间数mid,然后遍历数组,如果大于中间数的数的个数,那么说明重复的数字在前半段,我们类似递归的思想,再次在前半段执行,同样如果小于说明在后半段出现。这里注意我们是和mid比较而不是nums[mid],因为数字固定是在0~n之间的数字。时间复杂度还是O(nlogn),空间复杂度O(1)
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left = 0
right = len(nums) - 1
while(left <= right):
mid = left + (right - left)/2
count = 0
for i in range(len(nums)):
if nums[i] <= mid :
count += 1
if count > mid :
right = mid - 1
else:
left = mid + 1
return left
看到leetcode的提示有two points,这个一直不明白,看到别人的博客,原贴地址,https://segmentfault.com/a/1190000003817671
这里讲到了相应的原理,如果我们的序列是没有重复的,例如,[1,2,3]。那么可以由每一个下标对应一个数字,0->1 1->2 2->3,我们把这种映射关系应用出来,从下标0开始,找到0对应的数字,然后将这个数字作为新的下标找到新的数字,直到超出下界。比如这个例子中我们的路径就是0->1->2->3。
那么如果序列是重复的,[1,3,3,2],那么就会有下标对应数字时会有重复,0->1 {1,2}->3 3->2,那么我们的路径就会出现环! 0->1->3->2->3->2…,会出现3 2 这个环,那么环开始的地方就是重复的数字啦。这时我们利用的是leetcode中Linked List Cycle || 的方法,具体可以参见那篇博客。
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
slow = nums[0]
fast = nums[nums[0]]
while(slow != fast):
slow = nums[slow]
fast = nums[nums[fast]]
fast = 0
while(fast != slow):
slow = nums[slow]
fast = nums[fast]
return slow
最后
以上就是不安小笼包为你收集整理的leetcode 【287 Find the Duplicate Number】【Python】的全部内容,希望文章能够帮你解决leetcode 【287 Find the Duplicate Number】【Python】所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复