Leetcode——重新排序得到 2 的幂
Posted Yawn,
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode——重新排序得到 2 的幂相关的知识,希望对你有一定的参考价值。
1. 重新排序得到 2 的幂
(1)朴素枚举
//java
class Solution {
public boolean reorderedPowerOf2(int n) {
for(int i = 1;i < (int)1e9;i *= 2){
if(check(i,n)) return true; //枚举所有2的幂,一一与n进行词频比对
}
return false;
}
public boolean check(int i,int n){
int[] cnts = new int[10]; //统计每个数字的出现次数
while(i != 0){
cnts[i%10]++; //用i中每个数字的出现次数初始化cnts
i /= 10;
}
while(n != 0){ //看n中数字的出现次数能不能匹配上
if(cnts[n%10] == 0) return false;
else{
cnts[n%10]--;
}
n /= 10;
}
for(int j = 0;j < 10;j++){ //检查cnts数组是否全部为0,如果有不为0的位置说明该数字没匹配上
if(cnts[j] != 0) return false;
}
return true;
}
}
(2)DFS
对 n 进行重排,然后检查重排后的数值是否属于 2 的幂。
由于 2 的幂数固定,我们可以先通过「打表」将范围落在 [1, 1e9] 以内的 2 的幂预处理出来,这样我们可以在 O(1)的复杂度内判断某个数是否为 22 的幂。
//把范围内2的冥存入set中,再dfs暴搜即可
class Solution {
static Set<Integer> set = new HashSet<>();
static {
for (int i = 1; i < (int)1e9+10; i *= 2) set.add(i);
}
//统计每个数字的数字位数和出现次数
int m;
int[] cnts = new int[10];
public boolean reorderedPowerOf2(int n) {
//用n中每个数字的出现次数初始化cnts
while (n != 0) {
cnts[n % 10]++;
n /= 10;
m++;
}
return dfs(0, 0);
}
private boolean dfs (int u, int cur) {
//看数字的位数能不能匹配上
if (u == m) return set.contains(cur);
for (int i = 0; i < 10; i++) {
//检查cnts数组是否全部为0,如果有不为0的位置说明该数字没匹配
if (cnts[i] != 0) {
cnts[i]--;
if ((i != 0 || cur != 0) && dfs(u + 1, cur * 10 + i)) return true;
cnts[i]++;
}
}
return false;
}
}
(3)打表 + 词频统计
对于(1)我们发现复杂度上界取决于对 n 的重排,同时数据范围内的 2 的幂数量很少。
因此有效降低复杂度(避免重排)的做法是,直接枚举所有的 2 的幂 x,检查 x 的词频是否与 n 相同。
class Solution {
static Set<Integer> set = new HashSet<>();
static {
for (int i = 1; i < (int)1e9+10; i *= 2) set.add(i);
}
public boolean reorderedPowerOf2(int n) {
int[] cnts = new int[10];
while (n != 0) {
cnts[n % 10]++;
n /= 10;
}
int[] cur = new int[10];
//out:for是标签,用于跳出循环的。continue out / break out用于跳出包含它的最内层循环,continue out / break out可以直接跳出被out标记的循环。
out:for (int x : set) {
Arrays.fill(cur, 0);
while (x != 0) {
cur[x % 10]++;
x /= 10;
}
for (int i = 0; i < 10; i++) {
if (cur[i] != cnts[i]) continue out;
}
return true;
}
return false;
}
}
以上是关于Leetcode——重新排序得到 2 的幂的主要内容,如果未能解决你的问题,请参考以下文章
《LeetCode之每日一题》:194.重新排序得到 2 的幂