小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
869. 重新排序得到 2 的幂
给定正整数 N ,我们按任何顺序(包括原始顺序)将数字重新排序,注意其前导数字不能为零。
如果我们可以通过上述方式得到 2 的幂,返回 true;否则,返回 false。
- 示例 1:
输入:1 输出:true
- 示例 2:
输入:10 输出:false
- 示例 3:
输入:16 输出:true
- 示例 4:
输入:24 输出:false
- 示例 5:
输入:46 输出:true
解题思路
尝试数字的所有排列方式,检查每种排列方式是否能组成2的幂次(用set保存所有2的幂次)。
代码
class Solution {
Set<Integer> tar=new HashSet<>();
public boolean reorderedPowerOf2(int n) {
for (int i=0;i<31;i++)
{
tar.add(1<<i);
}
String s=""+n;
return dfsReorderedPowerOf2(s,new boolean[s.length()],0,new StringBuilder());
}
public boolean dfsReorderedPowerOf2(String s,boolean[] m,int cur,StringBuilder sb) {
if (cur==s.length()){
if (tar.contains(Integer.parseInt(sb.toString())))
return true;
return false;
}
boolean f=false;
for (int i = 0; i < m.length; i++) {
if (m[i]||cur==0&&s.charAt(i)=='0')continue;
m[i]=true;
sb.append(s.charAt(i));
f|=dfsReorderedPowerOf2(s,m,cur+1,sb);
sb.deleteCharAt(sb.length()-1);
m[i]=false;
}
return f;
}
}
优化
使用位运算优化,直接根据n&(n-1)可以判断是否为2的幂次。并且只生成每次排列以后组合成的数字,不使用字符串保存排列结果
class Solution {
public boolean reorderedPowerOf2(int n) {
String s=""+n;
return dfsReorderedPowerOf2(s,new boolean[s.length()],0,0);
}
public boolean dfsReorderedPowerOf2(String s,boolean[] m,int cur,int sum) {
if (cur==s.length()){
if ((sum&(sum-1))==0)
return true;
return false;
}
boolean f=false;
for (int i = 0; i < m.length; i++) {
if (m[i]||cur==0&&s.charAt(i)=='0')continue;
m[i]=true;
f|=dfsReorderedPowerOf2(s,m,cur+1,sum*10+s.charAt(i)-'0');
m[i]=false;
}
return f;
}
}