题目[题目及部分解法来自LeeCode]
solution one:
可以利用哈希表来完成本题!class Solution {
public int singleNumber(int[] nums) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int num : nums){
map.put( num, map.getOrDefault(num, 0) + 1 ); // nums数组元素值作为key,value统计出现次数
}
for(Map.Entry<Integer, Integer> item : map.entrySet()){ //利用entrySet方法来遍历哈希表元素,value值为1即为只出现一次的数字
if( item.getValue() == 1 ) return item.getKey();
}
return -1;
}
}
solution two:
利用位运算!利用与运算&,可以获取 nums[i] 的二进制形式的最右一位,每获取一位就利用无符号右移操作进行右移操作,即可获取num[i]的二进制形式每一位的值。 同时,建立数组 bitArray 来存储各二进制位1出现的次数。因为只有一个不重复数字,其余数字均重复三次,所以最后对3求余,则结果即为只出现一次数字的各二进制位。 最后,利用左移操作 和 或运算 ,可将 bitArray 数组中各二进位的值恢复到数字 res 上。
class Solution {
public int singleNumber(int[] nums) {
if(nums.length == 0) return -1;
int[] bitArray = new int[32];
for(int i = 0; i < nums.length ; ++i){
for(int j = 0; j < 32; ++j ){
bitArray[j] += nums[i] & 1; //存储各二进制位1出现的次数
nums[i] >>>= 1; //无符号右移(这里注意,二进制位由右向左依次进入bitArray数组)
}
}
int res = 0, m = 3;
for(int i = 0; i < bitArray.length; ++i){
res <<= 1; // 所以从bitArray.length - 1开始依次左移来进行恢复
res |= bitArray[31 - i] % m;
}
return res;
}
}