leetcode_power of 2/3 位运算

判断一个数是否是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;
}

 

posted @ 2016-03-12 21:55  sweetxy  阅读(278)  评论(0编辑  收藏  举报