题目一:找出数组中重复的数字。
在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
思路一:
解决这个问题一个简单方法是,我们只需要将数组排序,对排序后的数字找出重复的数字就简单很多,只需要从头到尾扫描排序后的数组就可以了,但是排序一个长度为n的数组最少的时间复杂度是nlog(n),显然不符合面试者的要求。
思路二:
我们可以利用哈希表,从头到尾依次遍历数组中的数字,每次遍历一个数字判断该数字是否在哈希表中,如果不在将此数字加入到哈希表中,如果在则找到了重复的数字,此算法的时间复杂度为O(n),但是是以空间复杂度为O(n)作为代价。不符合面试需求
思路三:
我们注意到题目的特殊性,数字都在0~n-1范围内,如果没有重复的数字,我们排好序之后,每一个数字与下标将会相同。如果有重复的数字,有些位置可能存在多个数字,可能没有数字。
依次遍历每个数字,当遍历到下标为i的数字m时,判断i是否等于m,如果i=m则继续往后遍历,如果不相等则判断m和下标为m的数字p是否相等,如果相等则找到了重复数字,如果不相等则交换两个数的位置,把m放到属于他的位置,然后重复比较、交换,直到找到重复的数字。
# -*- coding:utf-8 -*-
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
def duplicate(self, numbers, duplication):
# write code here
if not numbers:
return False
for index in range(len(numbers)):
while index != numbers[index]:
if numbers[index] == numbers[numbers[index]]:
duplication[0] = numbers[index]
return True
temp=numbers[index]
numbers[index]=numbers[temp]
numbers[temp]=temp
# 不能用以下交换方式 只能实现赋值不能实现交换
# a,b = b,a 是交换 ,此时b不同
# 因为赋值要先执行右边的程序,然后从左到右开始执行
# 当index=0 的时候
# 执行完右边的程序之后 numbers[numbers[index]]=numbers[2]=1
# numbers[index]=numbers[0]=2
# 等号左边从左向右执行 等号左边的第一个值先被赋值 即 numbers[index]=numbers[numbers[index]]=1
# 等号左边第二个值是关键 此时 numbers[index]已经被重新赋值为1 不是之前的2
# 所以numbers[numbers[index]]=numbers[1]=numbers[index]=2 右边的第二个值赋值给左边的第二个值
# numbers[index], numbers[numbers[index]] = numbers[numbers[index]], numbers[index]
return False
此题目中我把自己遇到的问题做如下总结:
python中交换两个数的时候 用
a,b = b, a 此时b相同则为交换,不相同为负值
# a,b = b,a 是交换 ,此时b不同
# 因为赋值要先执行右边的程序,然后从左到右开始执行
# 当index=0 的时候
# 执行完右边的程序之后 numbers[numbers[index]]=numbers[2]=1
# numbers[index]=numbers[0]=2
# 等号左边从左向右执行 等号左边的第一个值先被赋值 即 numbers[index]=numbers[numbers[index]]=1
# 等号左边第二个值是关键 此时 numbers[index]已经被重新赋值为1 不是之前的2
# 所以numbers[numbers[index]]=numbers[1]=numbers[index]=2 右边的第二个值赋值给左边的第二个值