136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
方法一:哈希表
用python的字典
时间O(n)
空间O(n)
class Solution:
def singleNumber(self, nums: List[int]) -> int:
#########哈希表 dict #########
#####时间O(n) 空间O(n)
mydict=dict()
for i in nums:
if i in mydict:
mydict[i]+=1
else:
mydict[i]=1
for i in mydict.keys():
if mydict[i]==1:
return i
方法二:按位异或
1.十进制下相同数字异或结果为0
2.数字a与0异或结果仍为原来的数字a
数组中所有数字进行异或,时间O(n)
空间O(1)
class Solution:
def singleNumber(self, nums: List[int]) -> int:
#######异或 ############
res=0
for i in nums:
res = res^i
return res
剑指 Offer 56 - I. 数组中数字出现的次数
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
方法:
考虑将数组分为两组,并且相同数字分在同一组,两个不同数字分别在不同的组,这样将本问题分为了两个问题一来解决。
那么如何将数组分为两组呢?
1.将数组中所有数字进行异或。(所得结果等于两个不同数字的异或结果)
2.选定该异或结果中为1的任意一位。(对于相同数字,该位数值一定相同,均为0或均为1;对于两个不同数字,该位数值必定不同,一个为0,一个为1)
3.以该位数值为依据,该位数值为1的分为一组,该位数值为0的分为一组。
class Solution:
def singleNumbers(self, nums: List[int]) -> List[int]:
#全体异或
xor_res=0
for i in nums:
xor_res = xor_res^i
#找到xorres中为1的任意一位
temp = 1
while xor_res & temp==0:
#从右向左查找 1&0=0说明该位为0 将temp中的1左移一位 1&1=1说明该位为1
#temp<<1 愚蠢的错误
temp = temp<<1
#temp 100000
#分组
res_1=0
res_2=0
for i in nums:
if i & temp ==temp:
res_1 ^= i
else:
res_2 ^= i
return [res_1,res_2]
剑指 Offer 56 - II. 数组中数字出现的次数 II
在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
方法一:哈希 JAVA map
class Solution {
public int singleNumber(int[] nums) {
Map<Integer,Integer> mymap = new HashMap();
for(int num:nums)
{
mymap.put(num,mymap.getOrDefault(num,0)+1);
}
for (Map.Entry<Integer,Integer> entry : mymap.entrySet())
{
int k = entry.getKey();
int v = entry.getValue();
if(v==1) return k;
};
// foreach 不会用md
// mymap.forEach((k, v) ->{
// if(v==1)
// int res=k;
// //return k;
// });
return 0;
}
}
方法二:有限状态自动机
统计所有数字的各二进制位中 11 的出现次数,并对 33 求余,结果则为只出现一次的数字。
https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/solution/mian-shi-ti-56-ii-shu-zu-zhong-shu-zi-chu-xian-d-4/