2023.12.09力扣每日一题——下一个更大的数值平衡数

2023.12.09

      • 题目来源
      • 我的题解
        • 暴力枚举法
        • 回溯法+二分

题目来源

力扣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);
            }
        }
    }

}

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈~

你可能感兴趣的:(力扣每日一题,java,leetcode,算法,职场和发展)