LeetCode902. 最大为 N 的数字组合

我们有一组排序的数字 D,它是 {‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’} 的非空子集。(请注意,‘0’ 不包括在内。)
现在,我们用这些数字进行组合写数字,想用多少次就用多少次。例如 D = {‘1’,‘3’,‘5’},我们可以写出像 ‘13’, ‘551’, ‘1351315’ 这样的数字。
返回可以用 D 中的数字写出的小于或等于 N 的正整数的数目。
示例 1:
输入:D = [“1”,“3”,“5”,“7”], N = 100
输出:20
解释:
可写出的 20 个数字是:
1, 3, 5, 7, 11, 13, 15, 17, 31, 33, 35, 37, 51, 53, 55, 57, 71, 73, 75, 77.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/numbers-at-most-n-given-digit-set
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

dfs 首先统计出1—LEN(n)-1位的数目,因为每个数字可以用任意次,所有每位的数目就是D.length^i(位数),在对len(n)位进行搜索,位数可能非常大,因此要加上记忆化. 当高位小于n的高位时,低位就不需要再判断大小了,这里用flag表示

class Solution {
    public int atMostNGivenDigitSet(String[] digits, int n) {
        int sum=0;
        char []ar=String.valueOf(n).toCharArray();
        for(int i=1;i<ar.length;i++)//i表示几位数字
        {
            sum+=(int)Math.pow(digits.length,i);;
        }
        //搜索 len[ar]位的数字
        memo=new int[2][ar.length+1];
        Arrays.fill(memo[0],-1);
        Arrays.fill(memo[1],-1);
        sum+=dfs(0,0,digits,ar);
        return sum;
    }
    int [][]memo;
    //falg==1->上一个高位大于n的上个高位
    int dfs(int n,int falg,String[]digits,char []ar)
    {
        if(memo[falg][n]!=-1)
            return memo[falg][n];
        if(n==ar.length)
        {
            return memo[falg][n]=1;
        }
        int num=0;
        for(int i=0;i<digits.length;i++)
        {
            char c=digits[i].charAt(0);
            if(falg==1 || c<=ar[n])
            {
                num+=dfs(n+1,falg==0&&c==ar[n]?0:1,digits,ar);
            }
        }
        return memo[falg][n]=num;
    }
}

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页