数位DP 详解及其案例实战 [模板+技巧+案例]

本文深入介绍了数位DP的概念,以案例leetcode233. 数字 1 的个数作为引入,探讨了数位DP的本质、适用问题和实际应用中的难点。文章提供了一个数位DP的典型模板,并详细解释了模板的各个部分,包括初始化、深度搜索和记忆化搜索。同时,文章分析了数位DP在解题中的应用,如在leetcode233和leetcode1012等题目中的实践,强调了前导0处理、记忆化搜索的选择以及难点剖析。
摘要由CSDN通过智能技术生成

零. 案例引入

1.案例引入 leetcode233. 数字 1 的个数

给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。

输入:n = 13
输出:6

2.暴力解

对于上述的案例,暴力解肯定是可行的,但时间复杂度较高,对于小于n的所有数字,直接遍历一遍即可

class Solution {
    public int countDigitOne(int n) {
        int sum = 0;
        for(int i = 1; i <= n; i++){
            sum += countone(i);
        }
        return sum;
    }
    public int countone(int n){
        char[] ch = Integer.toString(n).toCharArray();
        int sum = 0;
        for(int i = 0; i < ch.length; i++){
            if(ch[i] == '1'){
                sum++;
            }
        }
        return sum;
    }
}

 

3.引出数位DP

显然,上述方法肯定是会超时的,稍微数字大一些就会超时,那么对于数字类按位遍历的题目,可以考虑使用数位DP来解决。由于在以下论述中,会返回出现leetcode233. 数字 1 的个数leetcode1012 至少有 1 位重复的数字 这两道题目,需要提前看题。

一. 数位DP简单介绍

1.数位DP的本质

这里直接给出数位DP的本质:DFS+记忆化搜索(可选项)+约束(可选项)

那么为了更容易理解,还是以leetcode233. 数字 1 的个数为例,对于原题目,我们很容易得到下图中的疑问与结论(以n=123为例,且先不考虑数字1的个数,只是遍历所有可能结果):


通过观察上图,不难发现:

1. 除了少数情况外,大部分位置都可以取0~9

2. 蓝色情况框定了n可以取值的最大界限

3. 最前方出现的0可以看作不存在(按照题目要求不同,前导0可以不处理)

2.数位DP适合处的问题

(1)数位DP适合处理的典型问题:

      Ⅰ. 按位遍历的数字 或者 能组成按位遍历的数字

      Ⅱ. 暴力解简单但是数字稍微大一些就超时

      Ⅲ. 通常小于某个数的所有合集

(2)为何找规律的方法不建议使用

对于一些题目,找规律进行情况拆解判断当然也是可以的,可以做到更低的时间复杂度和空间复杂度,对于leetcode233. 数字 1 的个数这道题目,极致的找规律方法只需要几行{Ref. [3]}

public int countDigitOne(int n) {
    int count = 0;
    for (long k = 1; k <= n; k *= 10) {
        long r = n / k, m = n % k;
        count += (r + 8) / 10 * k + (r % 10 == 1 ? m + 1 : 0);
    }
    return count;
}

但是在面试笔试中,不管是时间上还是找边界条件和Bug都是不容易的一件事,使用模板更容易解决。

3.数位DP在实际使用面临什么难点

(1) 来到第i个位置,可以取什么数字?

(2)来到第i+1个位置,取值会受到i的影响吗?(本质和第一个是同一个问题)

(3)在某些情况下,不断取值的过程中有可以

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值