136. Single Number
题目描述:
Given an array of integers, every element appears twice except for one. Find that single one.
Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
题目翻译
给出一组整数数组,除了一个元素只出现一次外,其余都出现了两次。找出那个只出现一次的。
注意: 你的算法的时间复杂度应该是线性的。你可以不使用额外的存储空间来完成它吗?
解题方案
标签: Hash Table、Bit Manipulation
思路:
方法一:Hash Table(HashMap-Java)
- 遍历数组,将数组中的元素放入HashMap,无该值则放入,有该值则删除
- 如此,最后只剩下一个键值对,其中的key值就是所求
方法二:Bit Manipulation :
- 将一个数字和0异或,会得到该数字本身
a ⊕ 0 = a
- 两个相同的数字异或,会得到0
a ⊕ a = 0
- 并且有
a ⊕ b ⊕ a = ( a ⊕ a ) ⊕ b = 0 ⊕ b = b
- 因此,我们可以将所有元素异或来获得特别的那一个
- 时间复杂度: O(n)
- 空间复杂度: O(1)
方法三:Math :
- 使用数学方法,如鸡兔同笼问题的解法。
- 因为只有一个数出现了一次,所以用HashSet获取“头”的数目,出现了两次所以乘以2
- 然后减去遍历数组获取的“脚”的数目,即得到只出现了一次的元素。
- 时间复杂度: O(n+n)=O(n)
- 空间复杂度: O(n+n)=O(n)
( a + b + c ) * 2 - ( a + a + b + b + c ) = c
代码:
//方法一:Hash Table(HashMap)
class Solution {
public int singleNumber(int[] nums) {
if(nums.length==0||nums==null){
return 0;
}
HashMap<Integer , Integer> map = new HashMap<Integer , Integer>();
for(int i=0;i<nums.length;i++){
if(!map.containsKey(nums[i])){
map.put(nums[i],1);
}
else{
map.remove(nums[i]);
}
}
for(Map.Entry<Integer, Integer> m : map.entrySet()){
return m.getKey();
}
return 0;
}
}
//方法二:Bit Manipulation
class Solution {
public int singleNumber(int[] nums) {
int res = 0;
for(int i = 0; i < nums.length; i++){
res = res ^ nums[i];
}
return res;
}
}
//方法三:Math
class Solution {
public int singleNumber(int[] nums) {
if(nums.length==0||nums==null){
return 0;
}
int sum=0;
Set<Integer> set= (Set<Integer>) new HashSet();
for(int i=0;i<nums.length;i++){
set.add(nums[i]);
sum+=nums[i];
}
int sum2=0;
Iterator<Integer> ite=set.iterator();
while(ite.hasNext()){
sum2+=ite.next();
}
int result=2*sum2-sum;
return result;
}
}
参考资料
LeetCode- Bit Manipulation LeetCode总结(1) —— 位运算:http://blog.csdn.net/xsloop/article/details/47006241