136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
分析:
异或操作可以使我们巧妙地排除成对出现的数字,找出单独的数字,
两数相等“按位异或”会得零,零与任何数异或,得到任何数本身
代码:
public class LeetcodeTest {
public static void main(String[] args) {
Solution So = new Solution();
int[] nums = {2,2,1};
System.out.println(So.singleNumber(nums));
}
}
class Solution {
public int singleNumber(int[] nums) {
for(int i=1; i<nums.length; i++){
nums[0] ^= nums[i];
}
return nums[0];
}
}
260. 只出现一次的数字 III
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
示例 :
输入: [1,2,1,3,2,5]
输出: [3,5]
注意:
结果输出的顺序并不重要,对于上面的例子, [5, 3] 也是正确答案。
你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
分析:
先对nums数组内所有的数异或一遍,结果用a记录,a便是num1和num2异或的结果,
然后找到num1与num2不同的一位,用b记录这个位置,
最后再进行一遍for循环遍历,将nums数组中的数分为两拨,一拨在b记录的位置为0,与num1做异或操作,
一拨在b记录的位置不为0,与num2做异或操作,
最终得到的两个数字都出现一次,因为其他在这一位为0或不为0的数字都出现了两次或零次,被异或操作消除了。
代码:
public class LeetcodeTest {
public static void main(String[] args) {
Solution So = new Solution();
int[] nums = {1,2,1,3,2,5};
int[] res = So.singleNumber(nums);
System.out.println(res[0] + " " + res[1]);
}
}
class Solution {
public int[] singleNumber(int[] nums) {
int num1 = 0;
int num2 = 0;
//先异或一遍,得到num1和num2异或的结果
int a = 0;
for(int i=0; i<nums.length; i++){
a ^= nums[i];
}
//找到num1与num2不同的一位
int b = 1;
while((a & 1) ==0){
a >>= 1;
b <<= 1;//记录不同的位置
}
//将nums数组中的数分为两拨,一拨在b记录的位置为0,与num1做异或操作,一拨在b记录的位置不为0,与num2做异或操作,
//最终得到的两个数字都出现一次,因为其他在这一位为0或不为0的数字都出现了两次或零次,被异或操作消除了。
for(int i=0; i<nums.length; i++){
if((nums[i] & b) == 0){
num1 ^= nums[i];
}else{
num2 ^= nums[i];
}
}
return new int[] {num1,num2};
}
}