1、数组中只出现一次的数字
题目:一个整型数组中除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求空间O(1),时间O(n)。
思路:利用异或的性质,先求这两个数的异或结果,再找出结果的最低位1,然后根据该位是否为1把数组分成两组,分别计算两组的异或结果。
代码:
class Solution:
# 返回[a,b] 其中ab是出现一次的两个数字
def FindNumsAppearOnce(self, array):
# write code here
if len(array)<2:
return []
out = 0
for n in array:
out ^= n
flag = out - (out&(out-1))
a,b = 0,0
for n in array:
if n&flag:
a ^= n
else:
b ^= n
return [a,b]
2、数组中唯一只出现一次的数字II
题目:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了3次,找出那个只出现了一次的元素。要求空间O(1),时间O(n)
思路:1)从二进制位的角度来看,如果一个数出现三次,那么它的二进制表示的每一位(0或者1)也出现三次。把数组中所有数字的二进制表示的每一位都加起来,如果某一位的和能被3整除,则目标元素的该位是0,否则是1。需要辅助内存。
2)第一个掩码记录位次数出现一次,第二个掩码记录位次数出现2次。
class Solution:
def singleNumber(self, nums: List[int]) -> int:
seen_once = seen_twice = 0
for num in nums:
# 取反表示两个掩码标志位不能同时为1。
seen_once = ~seen_twice & (seen_once ^ num)
seen_twice = ~seen_once & (seen_twice ^ num)
return seen_once
3、数组中出现次数超过一半的数字
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:1)借助hashmap存储数组中每个数出现的次数,最后看是否有数字出现次数超过数组长度的一半
2)排序。数组排序后,如果某个数字出现次数超过数组的长度的一半,则一定会数组中间的位置。所以我们取出排序后中间位置的数,统计一下它的出现次数是否大于数组长度的一半;
3)某个数字出现的次数大于数组长度的一半,意思就是它出现的次数比其他所有数字出现的次数和还要多。因此我们可以在遍历数组的时候记录两个值:1. 数组中的数字;2. 次数。遍历下一个数字时,若它与之前保存的数字相同,则次数加1,否则次数减1;若次数为0,则保存下一个数字,并将次数置为1。遍历结束后,所保存的数字即为所求。最后再判断它是否符合条件。
4、数组中的重复数字
题目:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
思路:注意在长度为n的数组中,所有数字都在0到n-1的范围内,且有些数字是重复的,那么假如以这些数字的值去对应数组的下标,肯定有不同下标的值,对应了相同的下标,可以去遍历,遍历到每个以后,把数组中的值置为-1,那么下次第一次访问到这个-1的坐标的值,就是任意一个重复的值。
5、数组中出现两次的数字
题目:一个整型数组中包含N个整数,里面有两个整数出现两次,其余均只出现一次,请找出这两个整数,编程实现。
思路:1)sort+遍历
2)二叉搜索树
3)哈希表