判断一个数是否是2的次方:
public boolean isPowerOfTwo(int n) { if(n<0||n==0) return false; int remainder=n%2; int s=n/2; while(remainder==0){//remainder为0时继续做除法 remainder=s%2; s=s/2; } if(s==0) return true;//remainder不为0,此时看s是否变成0 return false; }
有bit解决方法,一个数如果是2的次方,那么二进制表达式为1后面跟若干个0,此时如果减1,则除高位外其他位均为1,将得到的新数与原数做与运算,得0,判断其为2的次方
public boolean isPowerOfTwo(int n) { return (n>0)&&(n&(n-1))==0;//用位运算做题 }
与之类似:power of three:
public boolean isPowerOfThree(int n) { if(n<0||n==0) return false; int remainder=n%3; int s=n/3; while(remainder==0){//remainder为0时继续做除法 remainder=s%3; s=s/3; } if(s==0&&remainder==1) return true;//注意这里不能仅仅判断s是否为0,还要判断remaider是否为1,因为还存在remainder为2的情况,此时n并不是3的次方数 return false; }
对于数字6,
6/3=2......0
2/3=0......2如果仅仅判断s==0,出错!在判断是否是2的次方数时,由于余数只可能是0,1所以不用对remainder进行判断,同理如果要判断一个数是否为4的次方数也要对remainder是否为1进行判断。
*********************************************
对于一个整数,求出二进制表达式中1的个数。利用Integer中的toBinaryString函数将整数转换为字符串形式:
public int hammingWeight(int n) { String s=Integer.toBinaryString(n); int count=0; for(int i=0;i<s.length();i++){ if(s.charAt(i)=='1') count+=1; } return count; }
********************************************
reverse Bits:
Reverse bits of a given 32 bits unsigned integer.
For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).注意:输入n=1时: 转换成1 (00000000000000000000000000000001),然后输出: 2147483648 (10000000000000000000000000000000),所以下图&&&&&处是31-i,但是如下代码是有错的!!!这在于double型存储的形式,2的31次方表示为:2.147483648E9,所以会出错!
public int reverseBits(int n) { double result0=0.0; String s=Integer.toBinaryString(n); int len=s.length(); for(int i=0;i<len;i++){ result0+=Math.pow(2,31-i)*(s.charAt(i)-48);//&&&&&&&& } String s1=String.valueOf(result0); int index=s1.lastIndexOf("."); int result=Integer.parseInt(s1.substring(0,index)); return result; }
必须用位运算解答此题。
*****************************************************************************
一个数组中除了一个整数出现一次,其他整数均出现两次。找出只出现了一次的这个数:
public int singleNumber(int[] nums) { HashMap<Integer,Integer> hs=new HashMap<Integer,Integer>(); for(int i=0;i<nums.length;i++){ if(hs.containsKey(nums[i])){ hs.put(nums[i],hs.get(nums[i])+1); }else{ hs.put(nums[i],1); } } Iterator<Map.Entry<Integer,Integer>> it=hs.entrySet().iterator();//注意这里使用的遍历方法 while(it.hasNext()){ Map.Entry<Integer,Integer> entry=it.next(); if(entry.getValue()==1) return entry.getKey(); } return 1; }
解法稍复杂。。可以直接用异或运算:
public int singleNumberEnhanced(int[] nums) { int result = 0; for (int num : nums) { result ^= num; } return result; }
出现两次的整数异或后为0,再与只出现一次的数异或得到此数本身。(ps:0与n异或,得n本身(不论n是几位数);所谓的1与其他数异或得翻转,是针对一位二进制数字)
研究下面的代码。。。。。。。。。。。。。。。。。。。。。。。。。。。singlenumber2
public static int singleNumber(int[] nums) { int len = nums.length, result = 0; for (int i = 0; i < 32; i++) { int sum = 0; for (int j = 0; j < len; j++) { sum += (nums[j] >> i) & 1; } result |= (sum % 3) << i; } return result; }