只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
要求: 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1] 输出: 1
示例 2:
输入: [4,1,2,1,2] 输出: 4
解题思路
我们可以使用集合存储数字。遍历数组中的每个数字,如果集合中没有该数字,则将该数字加入集合,如果集合中已经有该数字,则将该数字从集合中删除,最后剩下的数字就是只出现一次的数字。
但是这样时间和空间复杂度就会变大,并且题目要求我们不能使用额外的空间,所以可以考虑使用异或
异或(xor)
是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。其运算法则为:a⊕b = (¬a ∧ b) ∨ (a ∧¬b)
具体步骤如下:
- 第一步:初始化一个变量
ans
,当作结果 - 第二步:循环nums,将
ans ^ num
异或的结果赋值给ans - 第三步:返回ans
var singleNumber = function(nums) { let ans = 0; //遍历nums for(const num of nums) { //0异或第一个数,就等于这第一个数,获得的结果与下一个数异或 ans =ans ^ num; } return ans; };
知识点
如果a、b两个值不相同,则异或结果为1;如果a、b两个值相同,异或结果为0。
异或同时也满足交换律和结合律:a⊕b⊕a = (a⊕a)⊕b = 0⊕b = b
一个数和0做异或,结果是他本身
也就是说将数组里的数全部做异或,因为相同所以为0,那么就剩最后0与最后一个数做运算,结果就等于只出现一次的元素
2⊕3⊕5⊕7⊕2⊕3⊕5 就相当于 0⊕7=7