只出现一次的数字给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x21ib6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
最开始使用的代码(下面第一份代码不推荐):
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
let tempNums
tempNums = []
for (let i = 0; i < nums.length; i++) {
//如果有重复元素:
if (((nums.slice(i + 1, nums.length)).includes(nums[i]))) {
tempNums.unshift(nums[i])
}
}
for (let k in nums) {
while (tempNums.includes(nums[k])) {
nums.forEach(function (item, index) {
if (item === nums[k]) {
nums.splice(index, 1)
}
})
}
}
return nums
};
这里的思路是遍历一下数组,将重复出现的元素存到tempNums
中(每个重复元素只存储一个),
然后在遍历一次nums,如果nums中有tempNums中的数字,则使用splice删除一次
能跑完就不错,老菜鸡了
推荐代码(利用按位异或操作符):
这里是利用了按位异或操作符的计算,直接翻到文章末尾
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
let tempNum
for (let i in nums) {
tempNum ^= nums[i]
}
return tempNum
};
- 按位异或操作符:
这里要了解十进制的数字转为二进制,都是用0和1表示
的
例如:1 ^ 2
,它会将1,2转为二进制:1和10,
在按位异或操作中,它会依次对比各个位置上的数字
如果同一位置上只有一个1,则结果为1;如果同一位置上有两个1,则结果为0
例如下面代码:
//何为按位操作符:
console.log(1 ^ 2)// 1 ^ 10 = 11 => 3(11转为十进制得到3)
console.log(1 ^ 2 ^ 3)// 1 ^ 10 ^ 11
console.log(1 ^ 3)// 1 ^ 11
console.log(1 ^ 3 ^ 2)// 1^ 11 ^ 10
输出:
- 而解该题需要用到按位异或操作符的一个特性:
a ^ a = 0
a ^ 0 = a
a ^ b ^ c = a ^ c ^ b