数组
题目
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。算法应该具有线性时间复杂度。 不使用额外空间来实现。
解法
哈希集
使用集合存储数字。遍历数组中的每个数字,如果集合中没有该数字,则将该数字加入集合,如果集合中已经有该数字,则将该数字从集合中删除,最后剩下的数字就是只出现一次的数字。
java
class Solution {
public int singleNumber(int[] nums) {
HashSet<Integer> set = new HashSet<>();
for(int i =0;i<nums.length;i++){
if(!set.add(nums[i])){
set.remove(nums[i]);
}
}
//返回第一个元素
return `set.iterator().next();`
}
}
python
class Solution(object):
def singleNumber(self, nums):
one =[]
for i in nums:
if i not in one:
one.append(i)
else:
one.remove(i)
return one[0]
哈希表
使用哈希表存储每个数字和该数字出现的次数。遍历数组即可得到每个数字出现的次数,并更新哈希表,最后遍历哈希表,得到只出现一次的数字
java
class Solution {
public int singleNumber(int[] nums) {
Map<Integer,Integer> map = new HashMap<>();
for(Integer i:nums){
Integer count = map.get(i);
count = count == null?1:++count;
map.put(i,count);
}
for(Integer i:map.keySet()){
Integer count = map.get(i);
if(count == 1){
return i;
}
}
return -1;
}
}
python
class Solution(object):
def singleNumber(self, nums):
harshtable = dict()
for i in nums:
if i in harshtable:
harshtable[i] += 1
else:
harshtable[i] = 1
for i in harshtable.keys():
if harshtable[i] ==1:
return i
异或算法
做到线性时间复杂度和常数空间复杂度,使用位运算。
1.任何数和0做异或,结果仍然是原来的数
2.任何数和自身做异或运算,结果仍然是0
3.异或运算满足交换律和结合律。
相同的两个值做异或操作,所得为0,由于每个元素重复两次,在遍历后相互抵消,而唯一的元素只出现一次,故可以得到保留。
java
class Solution {
public int singleNumber(int[] nums) {
int ans = nums[0];
if (nums.length > 1) {
for (int i = 1; i < nums.length; i++) {
ans = ans ^ nums[i];
}
}
return ans;
}
}
python
class Solution(object):
def singleNumber(self, nums):
return reduce(lambda x, y: x ^ y, nums)
总结
1.考虑时间复杂度和空间复杂度
2.考虑偶数个元素一样
3.为大家的智慧点个赞