DeepSeek LintCode 3867 · 范围内的数字计数 public int digitsCount(int d, int low, int high)
LintCode 3867 · 范围内的数字计数问题分析计算在区间 [low, high] 中数字 d 出现的次数。核心思想使用数位DP或前缀和思想• count(low, high) count(0, high) - count(0, low-1)方法一逐位统计法推荐ACpublic class Solution {/*** param d: a digit* param low: the lower bound* param high: the upper bound* return: the number of d in the range from low to high*/public int digitsCount(int d, int low, int high) {return count(high, d) - count(low - 1, d);}// 计算 [0, n] 中数字 d 出现的次数 private int count(int n, int d) { if (n 0) return 0; long result 0; long base 1; // 当前位的权重1, 10, 100, ... while (base n) { // 将数字分为三部分高位、当前位、低位 long high n / (base * 10); // 高位 long cur (n / base) % 10; // 当前位 long low n % base; // 低位 if (d 0) { // 处理 d0 的特殊情况不能把前导零算进去 if (high 0) { if (cur d) { result high * base; } else if (cur d) { result (high - 1) * base low 1; } else { result (high - 1) * base; } } } else { // d ! 0 的情况 if (cur d) { result (high 1) * base; } else if (cur d) { result high * base low 1; } else { result high * base; } } base * 10; } return (int) result; }}方法二数位DP递归写法超时public class Solution {public int digitsCount(int d, int low, int high) {return dfs(high, d, true, false) - dfs(low - 1, d, true, false);}// limit: 是否受到上界限制 // lead: 是否有前导零 private int dfs(int n, int d, boolean limit, boolean lead) { if (n 0) return 0; String s String.valueOf(n); int len s.length(); int[][] memo new int[len][2]; for (int[] row : memo) Arrays.fill(row, -1); return dp(s, 0, d, limit, lead, memo); } private int dp(String s, int pos, int d, boolean limit, boolean lead, int[][] memo) { if (pos s.length()) { return lead ? 0 : 0; // 返回已统计的结果 } if (!limit !lead memo[pos][lead ? 1 : 0] ! -1) { return memo[pos][lead ? 1 : 0]; } int up limit ? s.charAt(pos) - 0 : 9; int res 0; for (int i 0; i up; i) { if (i d) { if (lead i 0) { // 前导零不计入 res dp(s, pos 1, d, limit i up, true, memo); } else { res dp(s, pos 1, d, limit i up, false, memo); } } else { res dp(s, pos 1, d, limit i up, lead i 0, memo); } } if (!limit !lead) { memo[pos][lead ? 1 : 0] res; } return res; }}算法解释逐位统计原理以 n 2593, d 5 为例统计十位为5的次数位置 高位 当前位 低位 贡献个位 259 3 0 26×126 (0-25的十位)十位 25 9 3 26×10260 (0-25的十位)百位 2 5 93 2×10094294 (0-199 200-259)复杂度分析方法 时间复杂度 空间复杂度逐位统计 O(log n) O(1)数位DP O(log n × 状态数) O(log n)推荐使用逐位统计法代码简洁高效
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2452399.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!