力扣2023.12.09每日一题;题序:2048
首先题目给出了数据范围0<=n<= 1 0 6 10^6 106,所以在这个范围内满足的最大数值平衡树是 666666。比666666更大的下一个数值平衡树是 1224444,所以只要n>=666666,则返回1224444。其他的则从n+1开始遍历到666666并判断是不是数值平衡树,只要找到立即返回。
时间复杂度:O(C−n),其中 C=1224444是可能为答案的最大的数值平衡数,取决于题目的数据范围。
空间复杂度:O(1)。
class Solution {
public int nextBeautifulNumber(int n) {
int res=1;
return getIsNum(n);
}
public int getIsNum(int n){
if(n>=666666)
return 1224444;
for(int i=n+1;i<=666666;i++){
int x=i;
int[] count=new int[10];
while(x>0){
count[x%10]++;
x/=10;
}
boolean f=true;
for(int d=0;d<10;++d){
if(count[d]>0&&count[d]!=d){
f=false;
break;
}
}
if(f)
return i;
}
return 1224444;
}
}
使用回溯实现重复数字的全排列(也就是进行打表),然后根据二分查找在表中查找到对应的值。
时间复杂度:O(n!+logC),其中 C=110是数值平衡数的个数,取决于题目的数据范围,n表示数字的位数。
空间复杂度:O©,其中 C=110 是数值平衡数的个数,取决于题目的数据范围。
class Solution {
public int nextBeautifulNumber(int n) {
int[] table=getTable();
Arrays.sort(table);
int i = Arrays.binarySearch(table, n + 1);
if (i < 0) {
i = -i - 1;
}
return table[i];
}
public int[] getTable(){
List<Integer> list= new ArrayList<>();
list.add(1);
list.add(22);
list.add(333);
list.add(4444);
list.add(55555);
list.add(666666);
list.add(1224444);
list.addAll(getOne(new int[]{1,2,2}));
list.addAll(getOne(new int[]{1,3,3,3}));
list.addAll(getOne(new int[]{1,4,4,4,4}));
list.addAll(getOne(new int[]{2,2,3,3,3}));
list.addAll(getOne(new int[]{1,2,2,3,3,3}));
list.addAll(getOne(new int[]{1,5,5,5,5,5}));
list.addAll(getOne(new int[]{2,2,4,4,4,4}));
int[] res=new int[list.size()];
for(int i=0;i<list.size();i++){
res[i]=list.get(i);
}
return res;
}
public List<Integer> getOne(int[] nums){
List<List<Integer>> list=permuteUnique(nums);
List<Integer> res=new ArrayList<>();
for(int i=0;i<list.size();i++){
int t=0;
List<Integer> l=list.get(i);
for(int bit:l){
t=t*10+bit;
}
res.add(t);
}
return res;
}
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
if (nums == null || nums.length == 0) {
return result;
}
Arrays.sort(nums);
boolean[] visited = new boolean[nums.length];
backtrack(result, new ArrayList<>(), nums, visited);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> tempList, int[] nums, boolean[] visited) {
if (tempList.size() == nums.length) {
result.add(new ArrayList<>(tempList));
} else {
for (int i = 0; i < nums.length; i++) {
if (visited[i] || (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1])) {
continue;
}
tempList.add(nums[i]);
visited[i] = true;
backtrack(result, tempList, nums, visited);
visited[i] = false;
tempList.remove(tempList.size() - 1);
}
}
}
}
有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈~