题目描述
给你一个 非空 整数数组
nums
,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
输入示例
我的思路
因为之前好像做过类似的题目,所以我的第一想法是先排序,再排除。题目明确说明同一个数只会出现两次,所以我的想法是把一样的数当成一组排除,设置一个index记录每一组的最后一个值的下标,每次更新为:index+=2;
for循环的nums[i]记录每一组的第一个值,i+=2,将两个值进行对比,如果相等就进入到下一组。这样就会出现四种情况:
①如[1,1,2,2,3,3,4]
②如[1,1,2,3,3,4,4]
③如[1,2,2]
④如[1]
代码如下:
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
nums.sort();
const len=nums.length;
let a=nums[1];
let index=1;
if(len==1)
{
return nums[0];
}
else{
for(let i=0;i<len;i+=2)
{
if(a!=nums[i])
{
return nums[i];
}
else{
if(index+2>len)
{
return nums[len-1];
}
index=i+2;
a=nums[index];
}
}
}
};
测试结果
因此可知是我归类的第二种情况没有通过,想了半天都没想明白,打开了题解,居然是用位运算解题。而且是异或运算。
题解
因为异或运算满足以下几个特点
一个数和 0 做 XOR 运算等于本身:a⊕0 = a
一个数和其本身做 XOR 运算等于 0:a⊕a = 0
XOR 运算满足交换律和结合律:a⊕b⊕a = (a⊕a)⊕b = 0⊕b = b
所以如果把所有数字做异或运算,剩下的就是唯一的数字。
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
let result=0;
for(let i=0;i<nums.length;i++)
{
result^=nums[i];
}
return result;
};