Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
题意:一个数组中除了一个数出现一次之外,其他数都出现了三次!!找出那个出现一次的数字!!!
public class Solution {
public int singleNumber(int[] nums) {
int ret=0;
int[] count=new int[32];
int len=nums.length;
for(int i=0;i<32;i++){
for(int j=0;j<len;j++){
//统计所有数字第i位0,1的和。通过右移与1做&运算得到!!!!!!
count[i]+=((nums[j]>>i)&1);
然后把对于位的和取模3就得到了single数字的第i位哦
count[i]=count[i]%3;
}
因为之前左移了i位,所以现在右移回来,然后与0做或|运算
所有的1就可以归为了!!!!!我曹真是6666
ret |=(count[i]<<i);
}
return ret;
}
}
PS:本来看了左老师的书,本来以为可以用K进制无进位加法做来着。详情见左老师书。但是不知道为什么不能通过。所以就上网扒拉了一个比较通用的方法。
输入是int型数组,所以可以用32位来表达输入数组的元素。
假设输入中没有single number,那么输入中的每个数字都重复出现了数字,也就是说,对这32位中的每一位i而言,所有的输入加起来之后,第i位一定是3的倍数。
现在增加了single number,那么对这32位中的每一位做相同的处理,也就是说,逐位把所有的输入加起来,并且看看第i位的和除以3的余数,这个余数就是single numer在第i位的取值。这样就得到了single number在第i位的取值。这等价于一个模拟的二进制,接着只需要把这个模拟的二进制转化为十进制输出即可。
为了完成上面的过程,需要使用一个数组 int a[ 32 ]来模拟位运算。
可以看出来,这个做法对于功力的要求非常高,需要看到数字的时候,眼前展现的是数字背后的二进制组成,要不然很难想到可以逐位去处理。
另外,这个做法可以扩展,如果有一堆输入,其中1个数字出现了1次,剩下的数字出现了K次,这样的问题全部可以使用这样的办法来做。
public class Solution {
public int singleNumber(int[] nums) {
//if(nums==null || nums.length<4)return 0;
int[] ret=new int[32];
for(int i=0;i!=nums.length;i++){
sum3(ret,nums[i]);
}
return gain101(ret);
}
public static void sum3(int[] ret,int nums){
// int[] ret=new int[32];
// for(int i=0;i<nums.length;i++){
// int[] cur=to3(nums[i]);
// for(int j=0;j<cur.length;j++){
// ret[j]=(ret[j]+cur[j])%3;
// }
// }
int[] cur=to3(nums);
for(int i=0;i!=ret.length;i++){
ret[i]=(ret[i]+cur[i])%3;
}
//return ret;
}
public static int[] to3(int num){
int[] ret=new int[32];
int index=0;
while(num!=0){
ret[index++]=num%3;
num=num/3;
}
return ret;
}
// public static int gain10(int[] arr){
// int ret=0;
// int temp=0;
// for(int i=0;i<arr.length;i++){
// temp=(int)Math.pow(3,i);
// ret=ret+arr[i]*temp;
// }
// return ret;
// }
public static int gain101(int[] arr){
int ret=0;
for(int i=arr.length-1;i!=-1;i--){
ret=ret*3+arr[i];
}
return ret;
}
}
转载于:https://blog.51cto.com/fulin0532/1908498