给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/single-number
作者:本人
思路:
建立一个哈希表,遍历数组,如果哈希表中有这个数组中这个数,那就删除,如果没有那就添加。
因为题目说了,其余元素都出现两次,所以进过这样的操作,哈希表中只有那一个我们想要的结果了,遍历哈希表,return即可。
class Solution {
public int singleNumber(int[] nums) {
int len = nums.length;
Map map = new HashMap();
for (int i = 0; i < len; i++) {
if (map.containsKey(nums[i])){
map.remove(nums[i]);
}else {
map.put(nums[i],nums[i]);
}
}
List list =new ArrayList<> (map.values()) ;
return list.get(0);
}
}
效果不好,肯定有更好的方法
作者:本人
思路
先将数组排序,然后让数组的第一个 - 第二个数 + 第三个数 - 第四个数 + 第五个数 ......
最终返回结果即可
例如:
排序后是[ 1, 1, 2, 2, 3] , 1-1+2-2+3 = 3
排序后是[ 1, 1, 2, 3, 3] , 1-1+2-3+3 = 2
排序后是[ 1, 2, 2, 3, 3] , 1-2+2-3+3 = 1
class Solution {
public int singleNumber(int[] nums) {
int len = nums.length;
Arrays.sort(nums);
int res = nums[0];
boolean flag = false;
for (int i = 1; i < len; i++) {
if (flag){
res = res + nums[i];
}else {
res = res - nums[i];
}
flag = !flag;
}
return res;
}
}
没想到这个笨办法的效率尽然高于方法1
作者:力扣官方
思路
什么是亦或?
亦或就是 : 同为0,不同为1,注意,指的是数字对应的二进制的每一位:同为0,不同为1
例如:4 ^ 1 = 5
4: 0100
1: 0001
亦或完毕:0101 ,也就是 5
对于这道题,可使用异或运算 ⊕。异或运算有以下三个性质。
class Solution {
public int singleNumber(int[] nums) {
int len = nums.length;
int res = nums[0];
for (int i = 1; i < len; i++) {
res = res ^ nums[i];
}
return res ;
}
}
版本答案
记住亦或的性质,尤其是:交换律和结合律