题目描述:
从正整数 N
开始,我们按任何顺序(包括原始顺序)将数字重新排序,注意其前导数字不能为零。
如果我们可以通过上述方式得到 2 的幂,返回 true
;否则,返回 false
。
示例 1:
输入:1
输出:true
示例 2:
输入:10
输出:false
示例 3:
输入:16
输出:true
示例 4:
输入:24
输出:false
示例 5:
输入:46
输出:true
提示:
1 <= N <= 10^9
解题思路:
本题理解的题意就是:给出一串数字,他的 第一个数字不为0的所有全排列中如果有2的幂返回true。
AC代码:
class Solution {
public:
bool reorderedPowerOf2(int n) {
int tmp;
vector<int> a;
while (n>0)
{
a.push_back(n % 10);
n /= 10;
}
sort(a.begin(), a.end());
do
{
if (a[0] == 0) continue;
tmp = 0;
for (int i = 0; i<a.size(); i++)
tmp = tmp * 10 + a[i];
for (int i = 0; i<30; i++)
if (tmp == (1 << i)) return true;
} while (next_permutation(a.begin(), a.end()));
return false;
}
};
个人尝试(内存超限):
其实下面这个才是我的原始代码,不过过不了,内存超限,感觉应该是全排列递归过程导致的,但是我不知道怎么解决。如果有大家有解决的办法,还希望能指教一下,先谢过了。
bool Powerof2(int n)
{
while (n>1)
{
if (n % 2 == 1)return false;
n = n / 2;
}
return true;
}
void Arrangement(vector<vector<int>>& res, vector<int> nums, int begin)
{
if (begin == nums.size())
{
res.push_back(nums);
return;
}
for (int i = begin; i < nums.size(); ++i)
{
if (i == begin || nums[i] != nums[begin])
{
swap(nums[i], nums[begin]);
Arrangement(res, nums, begin + 1);
swap(nums[i], nums[begin]);
}
}
}
bool reorderedPowerOf2(int N)
{
vector<int> nums;
while (N)
{
nums.push_back(N % 10);
N = N / 10;
}
vector<vector<int>> res;
Arrangement(res, nums, 0);
for (int i = 0; i < res.size(); i++)
{
if (res[i][0] == 0)continue;
int n = 0;
for (int j = 0; j < res[0].size(); j++)
{
n = n * 10 + res[i][j];
}
if(Powerof2(n)==true) return true;
}
return false;
}
逆向思维:
网上找了一会,还是没有解决全排列向量内存超限的问题,又看了一下其他牛人的AC代码,发现了一个新的思路。很佩服这些牛人的思维,感觉自己想法太僵化了。有待提升啊(^_^)。
牛人的解题思路:逆向思维,先枚举给定范围内所有的2的幂,然后将这些数字排序,然后和输入的数字排序后比较,相同即是。
bool reorderedPowerOf2(int N) {
if (N == 1) return true;
set<string> two;
for (int i = 0; i<40; i++) {
string s = to_string(1LL << i);
sort(s.begin(), s.end());
two.insert(s);
}
string s = to_string(N);
sort(s.begin(), s.end());
return two.find(s) != two.end();
}