开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
题目描述
给定正整数 n ,我们按任何顺序(包括原始顺序)将数字重新排序,注意其前导数字不能为零。
如果我们可以通过上述方式得到 2 的幂,返回 true;否则,返回 false。
示例 1:
输入: n = 1
输出: true
示例 2:
输入: n = 10
输出: false
提示:
1 <= n <= 10^9
解题思路
首先来看2的幂在规定范围内都有哪些数
1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
这是题目范围内的所有2的次方幂,统计数中每个数字出现的次数,
比如16: 1出现了1次,6出现了1次,那就可以写为 00112030405061708090,第一个数表示0,第二个数表示0出现的次数,第三个数表示1,第四个数表示1出现的次数,16中1出现了1次,以此类推。 1024: 0出现1次,1出现1次,2出现1次,4出现1次.写为 01112130415060708090
将这些数字都统计出来过后打表,再把n中所有数字出现的次数也写作这种模式作比较,如果在次方幂中找得到则返回true
代码
class Solution {
public boolean reorderedPowerOf2(int n) {
String[] strings = new String[]{"00112030405060708090", "00102130405060708090", "00102030415060708090", "00102030405060708190", "00112030405061708090", "00102131405060708090", "00102030415061708090", "00112130405060708190", "00102130405161708090", "00112130405160708090", "01112130415060708090", "01102130415060708190", "01102030415061708091", "00112130405060708191", "00112031415061708190", "00102131405061718190", "00102031405262708090", "01122131405060718090", "00112230425061708090", "00102230415160708290", "01112030415161718190", "01112230405160718091", "01112031435060708091", "01102031405061708490", "00122130405062738090", "00102133425260708090", "01112030415062718290","00122231415060728190","00102131425262708190","01112131405161718191"};
char[] chars = String.valueOf(n).toCharArray();
int[] nums = new int[10];
StringBuilder sb = new StringBuilder();
for (int i = 0,index = 0; i < chars.length; i++) {
nums[chars[i] - '0']++;
}
int index = 0;
for (int num : nums) {
sb.append(index++);
sb.append(num);
}
String s = sb.toString();
for (String string : strings) {
if (s.equals(string)) {
return true;
}
}
return false;
}
}
总结
如果用常规的回溯方法去判断,那么会有很多无用的操作,先预处理后打表也算得上一种投机取巧,因为2的幂次方数在int的范围内也不是有很多,可以用打表,如果本身数就很多就不能打表了。