private String[] digits;
private char s[];
private int dp[];
public int atMostNGivenDigitSet(String[] digits, int n) {
this.digits = digits;
s = Integer.toString(n).toCharArray();
dp = new int[s.length];
Arrays.fill(dp, -1); // dp[i] = -1 表示 i 这个状态还没被计算出来
return f(0, true, false);
}
public int f(int i,boolean lim,boolean fill) {
// 结束条件
if (i == s.length) {
return fill?1:0;
}
//一个状态中每个数位可以取任意值,所以需要无限制且已填过数
if (!lim && fill && dp[i] != -1) return dp[i];
int res = 0;
if(!fill)//之前不填,当前位也可选择不填,如果已填,则当前位必须填
res+=f(i+1,false,false);
int up = lim ? s[i] - '0' : 9;//如果没有限制,最大为9,否则为n对应位的数字
//如果之前已填,从0开始,否则从1开始
for (String digit :digits) {
int d=digit.charAt(0)-'0';
if(d>up) break;
res += f(i + 1, lim && d == up,true);//当前位有限制且为最大值时,下一位需要限制
}
//当前状态应为任意取值
if (!lim && fill) dp[i] = res;
return res;
}
2022.10.18-----leetcode.902
最新推荐文章于 2024-07-27 17:56:15 发布