题目连接:https://leetcode-cn.com/problems/reordered-power-of-2/
题目分析
如果直接顺着题目的思路,得到数字n的全排列,然后再去判断其是不是2的幂是比较复杂的。
我们应该注意到,因为数字是可以随意排列的,因此所有可以通过变换排列得到的数字都有相同个数的0、1、2,而
n
⩽
1
e
9
n\leqslant1e9
n⩽1e9,2的幂只有30个左右,我们可以先记录2的幂次然后再判断当前数字是不是和这些数字有相同的数字组合。
AC代码
class Int {
static constexpr int MAXN = 10;
public:
explicit Int(int x = 0);
array<int, MAXN> cnt;
friend bool operator == (const Int &lhs, const Int &rhs);
};
Int::Int(int x):cnt({0}) {
while (x) {
++cnt[x % 10];
x /= 10;
}
}
bool operator == (const Int &lhs, const Int &rhs) {
return lhs.cnt == rhs.cnt;
}
void init(vector<Int> &pow) {
constexpr int MAXN = 1e9;
int x = 1;
while (x < MAXN) {
pow.emplace_back(x);
x <<= 1;
}
}
class Solution {
public:
bool reorderedPowerOf2(int n) {
vector<Int> pow;
init(pow);
Int nn(n);
for (auto &integer : pow) {
if (integer == nn) return true;
}
return false;
}
};
题解分析
刚开始的时候考虑要不要使用二分查找,但是觉得这样的话还得排序,还得预处理,每次运行样例的时候都得处理一遍好像意义不大。
看了一下题解,发现题解在全局进行预处理,使用了匿名函数,第一次在C++里面见到这样使用匿名函数,的确很方便。
int i = []() -> int {
cout << "Hello world" << endl;
return 0;
}();
并且题解将数字映射成了一个字符串,这样就可以使用unorder_map
进行
O
(
1
)
O(1)
O(1)查询,感觉还是很巧妙的。