问题简述:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素
问题中有一个重要信息,除我们要找的那个元素,其余每个元素均出现两次,这降低了这道题的难度。
下面是几个解决办法:
排序再比较:
首先对数列进行排序,排序后在进行遍历的查找,因为最多出现两次,所以可以将数列分为两两一组,如果他们相等,则不是我们找的元素,跳入下一组进行比较,如果不相等,则就是我们要找的元素,返回他的值即可。
class Solution {
public int singleNumber(int[] nums) {
Arrays.sort(nums);
for(int i=0;i<nums.length-1;i++){ //用num.length-1是因为下面用到nums[i+1],防止超出
if(nums[i]==nums[i+1]){
i++; //因为是跳出一组,有两个数,所以在这加一再加上循环时的步伐刚好为2
}
else
return nums[i]; //两数不等,返回前者
}
return nums[nums.length-1]; //前面为了防止溢出,漏掉了最后一个值,如果刚好他就是我
//们要找的元素,即遍历前面没有找到答案,在此直接输出即可
}
}
异或运算:
我们可以利用异或运算,异或运算a ^ b “:
如果 a = b,a ^ b = 0;
如果 a != b,a ^ b = 1;
且a ^ 0 = a;再利用异或运算满足的交换律 a ^ b ^ c = a ^ c ^ b
所以我们依次对元素进行异或,最后便可以得出那个单独元素。
class Solution {
public int singleNumber(int[] nums) {
int a = 0;
for(int i=0;i<nums.length;i++){
a = a ^ nums[i];
}
return a;
}
}
利用Set集合:
利用set集合不能存入相同数据的特点,依次将数列中元素向Set集合中添加,若添加失败,则说明集合中已经有该数,也即就是这不是我们要找的那个元素,便可以把该元素删除。
直到最后,集合中剩余的那个元素便是单独元素,也是我们要找的元素。
class Solution {
public int singleNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for(int i=0;i<nums.length;i++){
if(!set.add(nums[i])) //集合中已添加该元素
set.remove(nums[i]); //不是我们找的元素,删除
}
return (int)set.toArray() [0]; //最后保留的即是单独元素
}
}
有问题欢迎大家讨论,谢谢