class Solution {
public int[] singleNumbers(int[] nums) {
int[] ans = new int[2];
int tmp = nums[0];
for (int i=1 ; i < nums.length ; i++) {
tmp = tmp ^ nums[i];
}
int index = 0;
int num = tmp;
while(num!=0) {
int a = num & 1;
if (a 1)
{
break;
}
num = num >> 1;
index ++;
}
// 找到异或值不同的位
int ans1 = tmp;
int ans2 = tmp;
//分组异或
for (int i=0;i<nums.length;i++) {
int a = (nums[i] >> index) & 1;
if (a 1)
{
ans1 ^= nums[i];
}else{
ans2 ^= nums[i];
}
}
ans[0] = ans1;
ans[1] = ans2;
return ans;
}
}
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int sum = 0;
for(int x : nums) sum ^= x;
int k = 0;
while(!(sum >> k & 1)) k++;
int first = 0;
for(int x : nums)
if(x >> k & 1) first ^= x;
return vector<int>{first, sum ^ first};
}
};
”’java
class Solution {
public int[] singleNumbers(int[] nums) {
int ret = 0;
for(int n : nums){
ret ^= n;
}
int div = 1;
while((div & ret) 0){
div <<=1;
}
int a=0,b=0;
//找出不一样的二进制位,相同的数还是被分到同一组
//最后遍历异或
for(int n:nums){
if((div & n) != 0){
a ^= n;
}else{
b ^= n;
}
}
return new int[]{a,b};
}
}
”’
时间复杂度O(n)
空间复杂度O(1)
class Solution {
public int[] singleNumbers(int[] nums) {
int[] res = new int[2];
int n = nums.length;
int z = 0;
for(int i=0;i<n;i++) {
z = z^nums[i];
}
int m = 1;
while((m&z) == 0) {
m=m<<1;
}
int x=0,y=0;
for(int i=0;i<n;i++) {
if((m&nums[i])==0) {
x=x^nums[i];
}else {
y=y^nums[i];
}
}
res[0]=x;
res[1]=y;
return res;
}
}
class Solution {
public int[] singleNumbers(int[] nums) {
int z = 0;
for(int i=0;i<nums.length;i++){
z ^= nums[i];
}
// 此时 z = x^y
// 从右向左遍历,找到第一位1
int m = 1;
while((z&m)==0){
// 循环左移,计算m
m<<=1;
}
// 将数组分成两个子数组,分别循环异或
int x =0;
int y=0;
for(int num: nums){
// m位置==1
if((num&m)!=0) x ^=num;
// m位置==0
else y^=num;
}
return new int[]{x,y};
}
}
class Solution {
public int[] singleNumbers(int[] nums) {
int z = 0;
for(int i = 0; i < nums.length; i++){
z = z ^ nums[i];
}
int m = 1;
while((m & z) == 0){
m = m << 1;
}
int x = 0, y = 0;
for(int i = 0; i < nums.length; i++){
if((nums[i] & m) == 0){
//结果为0的子数组,用异或统计x
x = x ^ nums[i];
}else{
//结果为1的子数组,用异或统计y
y = y ^ nums[i];
}
}
return new int[] {x,y};
//时间复杂度: O(n)
//空间复杂度: O(1)
}
}
class Solution {
public int[] singleNumbers(int[] nums) {
// 输入:nums = [4,1,4,6]
//输出:[1,6] 或 [6,1]
int[] res = new int[2];
// 先异或把2个不一样的数字异或结果搞出来
int temp = 0;
for (int i = 0; i < nums.length; i++) {
temp = temp ^ nums[i];
}
int index = 1;
// 把不同的数字分放在2组,这样就能异或找到他,2个不同的数字异或位必定至少有1位不同,找到这个位置,然后分2组异或即可
while ((temp & index) == 0) {
index = index << 1;
}
int a = 0, b = 0;
for (int i = 0; i < nums.length; i++) {
if ((index & nums[i])==0) {
a = a ^ nums[i];
} else {
b = b ^ nums[i];
}
}
res[0] = a;
res[1] = b;
return res;
}
}
class Solution {
public int[] singleNumbers(int[] nums) {
int x = 0, y = 0, n = 0, m = 1;
for(int num : nums)
n ^= num;
while((n & m) == 0)
m <<= 1;
for(int num: nums) {
if((num & m) != 0) x ^= num;
else y ^= num;
}
return new int[] {x, y};
}
}
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int z = 0;
for(int i = 0;i < nums.size();++i){
z ^= nums[i];
}
int m = 1;
while((m & z) == 0){
m = m << 1;
}
int x = 0,y = 0;
for(int i = 0;i < nums.size();++i){
if((nums[i] & m) == 0){
x ^= nums[i];
}
else{
y ^= nums[i];
}
}
return vector<int>{x,y};
}
};
func singleNumbers(nums []int) []int {
//将数字分为两组,独特数字不同组,相同为一组
//a^b的结果
res := 0
//a,b两数为出现一次的数字
a, b := 0, 0
for _, v := range nums {
res ^= v
}
index := 0
for res & 1 == 0 {
index +=1
res >>= 1
}
for _, v := range nums {
if (v >> index) & 1 == 0 {
a ^= v
} else {
b ^= v
}
}
return []int{a, b}
}
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
/*
整个算法的流程比较复杂
1. 所有的数字进行异或,会得到结果z。这个z是两个只出现一次的数字x和y的异或的结果
2. 求得第n个二进制位不相同。
e.g. x = 1000
y = 0110
--------
z = 1110
这个时候需要用一个不断向左移位的1来相与得到第n个二进制位不相同。
n = 0010
3. 用这个n去对原来的数组进行相与,是肯定能把x和y分到两个子问题中去的。
此时问题就变成了数组中数字只出现一次的两个子问题
然后对x和y分别进行异或
*/
int z = 0; // x ^ 0 = x
for(int num:nums){
z ^= num;
}
int n = 1;
while((z & n) == 0){
n <<= 1;
}
int x = 0;
int y = 0;
for(int num:nums){
cout<< (num & n) <<endl;
if((num & n) == 0){//(num & n)得有括号,不然优先级不如==
x ^= num;
}
else{
y ^= num;
}
}
return {x,y};
}
};
class Solution {
public int[] singleNumbers(int[] nums) {
int n = 0;
for(int num : nums){
n ^= num;//假设出现一次的两个数字为a,b,则n = a ^ b
}
int lastOne = n & ((~n) + 1);//获取最后一个一
int a = 0;
for(int num : nums){
if((num & lastOne) != 0) a ^= num;
}
return new int[]{a, (n ^ a)};
}
}
共以下 18 个回答
class Solution {
public int[] singleNumbers(int[] nums) {
int[] ans = new int[2];
int tmp = nums[0];
for (int i=1 ; i < nums.length ; i++) {
tmp = tmp ^ nums[i];
}
int index = 0;
int num = tmp;
while(num!=0) {
int a = num & 1;
if (a 1)
{
break;
}
num = num >> 1;
index ++;
}
// 找到异或值不同的位
int ans1 = tmp;
int ans2 = tmp;
//分组异或
for (int i=0;i<nums.length;i++) {
int a = (nums[i] >> index) & 1;
if (a 1)
{
ans1 ^= nums[i];
}else{
ans2 ^= nums[i];
}
}
ans[0] = ans1;
ans[1] = ans2;
return ans;
}
}
“`c++ singleNumbers(vector & nums) {{x, y};
class Solution {
public:
vector
int z=0;
int i;
for(i=0;i
}
};
c++ 代码 位运算的运用 singleNumbers(vector & nums) {x,y};
class Solution {
public:
vector
{ int no=0,x=0,y=0,m=1;
for(int i=0;i<nums.size();i++)
no^=nums[i];
while(!(no & m)) // 2. 循环左移,计算 m
m <<= 1;
for(int i=0;i<nums.size();i++)
{
if(nums[i]&m) x^=nums[i];
else
y^=nums[i];
}
return vector
};
”’java
class Solution {
public int[] singleNumbers(int[] nums) {
int ret = 0;
for(int n : nums){
ret ^= n;
}
int div = 1;
while((div & ret) 0){
div <<=1;
}
int a=0,b=0;
//找出不一样的二进制位,相同的数还是被分到同一组
//最后遍历异或
for(int n:nums){
if((div & n) != 0){
a ^= n;
}else{
b ^= n;
}
}
return new int[]{a,b};
}
}
”’
时间复杂度O(n)
空间复杂度O(1)
思路:通过位运算找到不相同的两个数的从右往左数不同位,然后利用这个数将这两个数分开,然后得到两个子数组,虽然这两个数组的元素个数不确定,但是相同元素可定被分到同一组,这样两个数组直接进行异或得到的还是各自数组中只出现一次那个数
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public int[] singleNumbers(int[] nums) {
//经典与或的 场景
int a =nums[0];
for(int i=1;i<nums.length;i++)
{
a=a^nums[i];
}
//a = num1 ^ num2;
//把a分成两部分 因为 num1 和num2 两数不同 一定有一位二进制
// a & 0001 a&00010 选择m 不停左移
int m =1;
while((a&m)0)
{
m<<=1;
}
//此时 m能表示哪一位 num1 num2 里面不相同的位置
int x=0;
int y=0;
for(int i=0;i<nums.length;i++)
{
if((nums[i]&m)0)
{
x=x^nums[i];
}else
{
y=y^nums[i];
}
}
int [] result=new int[]{x,y};
return result;
}
}
7.25
Day17:下面是代码
代码
没接触过根本想不到啊,主要是异或操作,另外找到第一个不同位置然后将数组分成两组的操作也很巧妙。
没怎么做过,有点难住了,看题解弄懂了。
分组异或