【LeetCode 338】比特位计数

【LeetCode 338】比特位计数_第1张图片

这是一个动态规划题目,主要思路就是利用已经计算的结果获得当前求解的结果,递推式通常通过反推获得。

方法1:获得一个比当前数字小的数字,最简单的方法就是右移。

查阅(当前数字>>2)的结果,如果当前数字是偶数,直接返回,如果当前数字是奇数,需要加上最低位的一个1。

    public int[] countBits(int num) {
        int[] answer=new int[num+1];
        Arrays.fill(answer,-1);
        for(int i=num;i>=0;i--){
            countBitsCore(i,answer);
        }
        return answer;
    }

    public int countBitsCore(int num, int[] answer){
        if(num==0) return answer[num]=0;
        if(answer[num]!=-1) return answer[num];
        answer[num]=num%2==0?countBitsCore(num>>1,answer):countBitsCore(num>>1,answer)+1;
        return answer[num];
    }

 

方法2:通过列举的方法寻找规律。

...

01000110

01000111

01001000

...

通过列举就可以发现,相邻两个数字的二进制变化规律,根据i-1是奇数或偶数,分为两种情况:
(1)如果i-1是偶数,i相比i-1只变化了最后一位,所以直接用i-1的答案加1即可;f(i)=f(i-1)+1;
(2)如果i-1是奇数,比如01000111,那么i就是01001000,可以发现i-1低位连续的1变成了0,并且i相比i-1多了一个1(进位的那个),i&(i-1)之后的结果是01000000,比i小且比i少一个bit 1。f(i)=f(i&(i-1))+1;

    public int[] countBits(int num) {
        int[] answer=new int[num+1];
        Arrays.fill(answer,-1);
        for(int i=num;i>=0;i--){
            countBitsCore(i,answer);
        }
        return answer;
    }

    public int countBitsCore(int num, int[] answer){
        if(num==0) return answer[num]=0;
        if(answer[num]!=-1) return answer[num];
        answer[num]=num%2==0?countBitsCore(num&(num-1),answer)+1:
                             countBitsCore(num-1,answer)+1;
        return answer[num];
    }

 

你可能感兴趣的:(LeetCode,算法基本功)