SingleNumber

来源:互联网 发布:android 网络编程 编辑:程序博客网 时间:2024/05/16 09:03

1)一个数组中一个元素出现一次,其他元素出现基数(k)次

<1>用m个数去记录数字出现的次数(X1,..,Xm),且2^m>=k,(当我们记录到一个数出现k次时,就可以将这个数消去);

<2>初始状态X1...Xm=0,当遍历到一个数为1时X1=1,只有当X1==1,并且当前遍历的数为1时,X2才变为1即:X2=X2^(X1&i),同样地,我们可以得出Xm=Xm^(xm-1 & ... & x1 & i)

<3>当基数器(X1,..,Xm)达到k时我们需要将其清0,最后我们使用一个mask变量去和X1...Xm相与,当基数器到达K时,mask为0,当计数器<k时,mask为1;

<4>将K表达成二进制的形式(k1...km),将mask表示成~(x1' & x2' & ... xm'),where xj' = xj if kj = 1 and xj' = ~xj if kj = 0 (j = 1 to m).例如:k=5:k1=1,k2=0,k3=1;mask=~(x1&~x2&x3);另:根据单独出现P次的某个数,返回某个值,eg:p=1(001),返回x1;p=3(101);返回x1或x3;

public int singleNumberII(int nums[])

{

int xm=0...x1=0;

int mask=0;

for()

{

xm ^= (xm-1 & ... & x1 & i);

xm-1 ^= (xm-2 & ... & x1 & i);

.....

x1 ^= i;

mask = ~(x1' & x2' & ... xm') where xj' = xj if kj = 1 and xj' = ~xj if kj = 0 (j = 1 to m).

xm &= mask;

......

x1 &= mask;

}

 

2)一个数组中两个元素出现一次,其他元素出现两次(偶数次),求出出现一次的两个元素

 首先将所有元素异或,得到一个不为0的数x,根据x的某一位不为0 的数将数组分为两部分,则这两个数分别被分到这两个部分,由于其他数成对出现,故他们相同的在同一部分

eg:

public int[] Singlenumber(int nums[])

{

int x=nums[0];

for(int i=1;i<nums.length;i++)

{

x^=nums[i];

}

x=x&(-x);

int a=0,b=0:

for(int i=0;i<nums.length;i++)

{

if(nums[i]&x==1)a^=nums[i];

else b^=nums[i];

}

int []num=new int[]{a,b};

return num;

}

3)一个数组中三个元素出现一次,其他元素出现两次(偶数次),求出出现一次的三个元素

将三个数分成两部分,其中一个就为三个数之中的一个数,然后题目就变为了2),将数组以后得到x=a^b^c;然后再将A=x^a=b^c,B=x^b=a^c,c=x^c=b^c;

A!=B!=C!=0,N=A^B^C==0;

若三个数的异或为0,则其中一个数的某位为1,另外两个数的以为为1,另一个数的以为为0,N=N&(-N);求出该位为1的数;即求出其中一个数,剩下的问题转为2)

eg:

 

public int  exec_(int n)return n&(-n);

 

public int[] SingleNumber(int nums[])

{

int x=nums[0];

for(int i=1;i<nums.length;i++)

{

x^=nums[i];

}

//falg为那个单独的两个数的异或的值

int flag=0;

for(int i:nums)

{

flag^=exec_(x^i);

}

//将其找出,原问题变为(2)

int x1=0;

for(int i:nums)

{

int val=i^x;

if(val&flag==1)x1^=val;

}

int num1=x1^x;

x=num1;

//变为(2)

for(int i;nums)

{

x^=i;

}

x=exec(x);

int num2=0,num3=0;

for(int i:nums)

{

if(x&i==1)nums2^=i;

else nums3^=i;

}

int n[]=new int[]{num1,num2,num3};


return n;

}

 

0 0
原创粉丝点击