题目描述:single-number1
一个数组中除了一个数字外,其余数字均出现两次,找出只出现一次的数字。
要求线性复杂度
方法:两个相同的数字异或得0,一个数字和0异或结果是它本身。
public class Solution {
public int singleNumber(int[] nums) {
int num=0;
for(int i=0;i<nums.length;i++)
{
num=num^nums[i];
}
return num;
}
}
题目描述:single-number2
一个数组中除了一个数字外,其余数字均出现3次,找出只出现一次的数字。
要求线性复杂度
通法:O(32*N),这是一个通用的解法,如果把出现3次改为 k 次,那么只需模k就行了。
public class Solution {
public int singleNumber(int[] nums) {
/* 把所有整数按照32位二进制进行每一位上的与1运算 结果为3n或3n+1
为3n+1的那些位就是只出现一次的数的二进制中1所在的位
*/
int result=0;
for(int i=0;i<32;i++)
//记录在i位上1的个数;
{
int count=0;
for(int j=0;j<nums.length;j++)
{
count+=(nums[j]>>i)&1;
}
//把3n+1的那些位的1移回原位并累加起来 |= 也行
result+=(count%3)<<i;
}
return result;
}
}
题目描述:一个整型数组中除了两个数字,其他数字都出现了两次。找出这两个只出现一次的数字。
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2)
{
if(data.size()<2)
return;
int num=0;
for(int i=0;i<data.size();i++)
{
num=num^data[i];
}
if(num==0)
return;
//用flag找出num第一个不为0的位
int flag=1;
while((num&flag)==0)
{
flag=flag<<1;
}
*num1=*num2=0;
for(int i=0;i<data.size();i++)
{
if(data[i]&flag)
*num1^=data[i];
else
*num2^=data[i];
}
}
};
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array == null||array.length < 2)
return ;
//算出异或1
int num=0;
for(int i: array)
{
num=num^i;
}
int index_1=index_func(num);
//num1,num2赋值
for(int i: array)
{
if(to_right(i,index_1))
num1[0]^=i;
else
num2[0]^=i;
}
}
//右边第几位是1
public int index_func(int num)
{
int count=1;
while((num&1) == 0)
{
num=num>>1;
count++;
}
return count;
}
//数字移位
public boolean to_right(int num,int count)
{
if(((num>>count-1)&1) == 1)
return true;
else
return false;
}
}