leetcode 338.比特币计位

  DP的算法就不说了,记一种打表找规律法(大草)。

  通过打表,我们发现答案如下:

2    1
3-4   2 1
5-8   2 2 3 1
9-16   2 2 3 2 3 3 4 1
17-32  2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 1
33-64  2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 1

  可以很容易发现规律:

2    1
3-4   2 1
5-8   2 2 3 1
9-16   2 2 3 2 3 3 4 1
17-32  2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 1
33-64  2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 1

  即图中深蓝数段就是浅蓝段整体+1。这样我们可以猜测出65-128的结果:

65-128  2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 3 4 4 5 4 5 5 6 4 5 5 6 5 6 6 7

  经过对拍,和暴力程序给出的答案完全一致,因此可以认为这个规律是正确的。

  代码:

 

class Solution {
public:
    vector<int> countBits(int n){
        vector<int> ans;
        ans.push_back(0);
        if (n==0)    return ans;
        ans.push_back(1);
        if (n==1)    return ans;
        ans.push_back(1);
        if (n==2)    return ans;
        ans.push_back(2);
        if (n==3)   return ans;
        ans.push_back(1);
        if (n==4)   return ans;
        int t=8,tt;
        while (t<=n){
            tt=t>>1;
            for (int i=(t>>2)+1;i<tt;i++)
                ans.push_back(ans[i]);
            ans.push_back(2);
            tt=(t>>1)+(t>>2);
            for (int i=(t>>1)+1;i<tt;i++)
                ans.push_back(ans[i]+1);
            ans.push_back(1);
            t<<=1;
        }
        if (n<(t>>1)+(t>>2)){
            t=(t>>1)+1;
            int i=(t>>1)+1;
            while (t<=n){
                ans.push_back(ans[i]);
                i++,t++;
            }
        }
        else if (n==(t>>1)+(t>>2)){
            t=(t>>1)+1;
            int i=(t>>1)+1;
            while (t<n){
                ans.push_back(ans[i]);
                i++,t++;
            }
            ans.push_back(2);
        }
        else{
            tt=t-(t>>2),t=(t>>1)+1;
            int i=(t>>1)+1;
            while (t<tt){
                ans.push_back(ans[i]);
                i++,t++;
            }
            ans.push_back(2);
            t=tt+1,i=(tt<<1)/3+1;
            while (t<=n){
                ans.push_back(ans[i]+1);
                t++,i++;
            }
        }
        return ans;
    }
};

 

leetcode 338.比特币计位

 

leetcode 338.比特币计位

上一篇:rz使用


下一篇:[非专业翻译] Mapster - 映射配置