题目链接:https://leetcode.com/problems/single-number/、https://leetcode.com/problems/single-number-ii/、https://leetcode.com/problems/single-number-iii/
思路一:最朴素的思路就是使用哈希算法来做这三条题目,代码都差不多
Single Number 代码:
class Solution {
public int singleNumber(int[] nums) {
HashSet<Integer> set=new HashSet<Integer>();
for(int i=0;i<nums.length;i++)
{
if(set.contains(nums[i]))
set.remove(nums[i]);
else
set.add(nums[i]);
}
Iterator<Integer> it=set.iterator();
return it.next();
}
}
Single Number II代码:
class Solution {
public int singleNumber(int[] nums) {
HashMap<Integer,Integer> map=new HashMap();
for(int i=0;i<nums.length;i++)
{
if(map.containsKey(nums[i]))
map.put(nums[i],map.get(nums[i])+1);
else
map.put(nums[i],1);
}
for(Integer i:map.keySet())
{
if(map.get(i)!=3)
return i;
}
return 0;
}
}
Single Number III代码:
class Solution {
public int[] singleNumber(int[] nums) {
int[] ret=new int[2];
HashMap<Integer,Integer> map=new HashMap();
for(int i=0;i<nums.length;i++)
{
if(map.containsKey(nums[i]))
map.put(nums[i],map.get(nums[i])+1);
else
map.put(nums[i],1);
}
int k=0;
for(Integer i:map.keySet())
{
if(map.get(i)==1)
ret[k++]=i;
}
return ret;
}
}
这个思路的解法效率理论上都是线性的,但是效率不高。思路一不是关键,下面来看一种神奇的基于位运算的高效思路及其解法,这个思路是看的Solutions和Discussion的,真的很牛逼:
利用位运算中异或运算XOR的特殊属性来做
异或运算的三条性质如下:
Single Number思路二代码:
class Solution {
public int singleNumber(int[] nums) {
int ret=0;
for(int i:nums)
ret^=i;
return ret;
}
}
Single Number思路二代码:
参考这个解释https://leetcode.com/problems/single-number-ii/discuss/43296/An-General-Way-to-Handle-All-this-sort-of-questions.
public class Solution {
public int singleNumber(int[] nums) {
int a=0;
int b=0;
for(int c:nums){
int ta=(~a&b&c)|(a&~b&~c);
b=(~a&~b&c)|(~a&b&~c);
a=ta;
}
return a|b;
}
}