1.题目
给定一个按非递减顺序排列的数字数组 digits 。你可以用任意次数 digits[i] 来写的数字。例如,如果 digits = [‘1’,‘3’,‘5’],我们可以写数字,如 ‘13’, ‘551’, 和 ‘1351315’。
返回可以生成的小于或等于给定整数 n 的正整数的个数。
示例 1: 输入:digits = [“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.
示例 2: 输入:digits = [“1”,“4”,“9”], n = 1000000000 输出:29523 解释: 我们可以写 3 个一位数字,9 个两位数字,27 个三位数字, 81 个四位数字,243 个五位数字,729 个六位数字, 2187 个七位数字,6561 个八位数字和 19683 个九位数字。 总共,可以使用D中的数字写出 29523 个整数。
示例 3: 输入:digits = [“7”], n = 8 输出:1
提示: 1 <= digits.length <= 9 digits[i].length == 1 digits[i] 是从 ‘1’ 到 ‘9’ 的数 digits 中的所有值都不同 digits 按 非递减顺序 排列 1 <= n <= 109
来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/numbers-at-most-n-given-digit-set 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.思路
(1)数位 dp 思路参考该 LeetCode 用户题解。
3.代码实现(Java)
class Solution {
private String[] digits;
private char[] s;
private int[] dp;
public int atMostNGivenDigitSet(String[] digits, int n) {
this.digits = digits;
this.s = Integer.toString(n).toCharArray();
this.dp = new int[s.length];
Arrays.fill(dp, -1);
return digitDp(0, true, false);
}
private int digitDp(int i, boolean isLimit, boolean isNum) {
if (i == s.length) {
return isNum ? 1 : 0;
}
if (!isLimit && isNum && dp[i] >= 0) {
return dp[i];
}
int res = 0;
if (!isNum) {
res = digitDp(i + 1, false, false);
}
char up = isLimit ? s[i] : '9';
for (String d : digits) {
if (d.charAt(0) > up) {
break;
}
res += digitDp(i + 1, isLimit && d.charAt(0) == up, true);
}
if (!isLimit && isNum) {
dp[i] = res;
}
return res;
}
}
|