给定正整数 N ,我们按任何顺序(包括原始顺序)将数字重新排序,注意其前导数字不能为零。

如果我们可以通过上述方式得到 2 的幂,返回 true;否则,返回 false。

示例 1:

输入:1 输出:true 示例 2:

输入:10 输出:false 示例 3:

输入:16 输出:true 示例 4:

输入:24 输出:false 示例 5:

输入:46 输出:true  

提示:

1 <= N <= 10^9

题解: 想到了一个好方案,就是预处理出2的30次方以内每个数中各个数字的个数,然后将输入的值进行比较。这里使用了multiset,其实map也是可以搞定的。

class Solution {
public:
    bool reorderedPowerOf2(int n) {
        if(n == 1) return true;
        multiset<int> now;
        //处理输入的数字
        while(n > 0){
            //cout<<n % 10<<endl;
            now.insert(n % 10);
            n /= 10;
        }
        
        //预处理出2^30以内的2的幂中包含的数字
        long long cheng = 1;
        for(int i = 0; i < 30; i++){
            cheng *= 2;
            long long tmp = cheng;
            multiset<int> ind;
            while(tmp > 0){
                ind.insert(tmp % 10);
                tmp /= 10;
            }
            if(now == ind) return true;
        }

        return false;
    }
};

还有一种方案是采用搜索回溯+位运算。 alt

class Solution {
    vector<int> vis;

    bool isPowerOfTwo(int n) {
        return (n & (n - 1)) == 0;
    }

    bool backtrack(string &nums, int idx, int num) {
        if (idx == nums.length()) {
            return isPowerOfTwo(num);
        }
        for (int i = 0; i < nums.length(); ++i) {
            // 不能有前导零
            if ((num == 0 && nums[i] == '0') || vis[i] || (i > 0 && !vis[i - 1] && nums[i] == nums[i - 1])) {
                continue;
            }
            vis[i] = 1;
            if (backtrack(nums, idx + 1, num * 10 + nums[i] - '0')) {
                return true;
            }
            vis[i] = 0;
        }
        return false;
    }

public:
    bool reorderedPowerOf2(int n) {
        string nums = to_string(n);
        sort(nums.begin(), nums.end());
        vis.resize(nums.length());
        return backtrack(nums, 0, 0);
    }
};

alt