持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
每日力扣是一个专门用来讲力扣中国每天发布的每日一题的栏目。本专栏不提供题目的解答源码,只讲解思路,目的是养成每日刷题、提高自己手感,从而达到算法熟练的目标。
题目(已做删减处理)
给定一个按 非递减顺序 排列的数字数组
digits。你可以用任意次数digits[i]来写的数字。例如,如果digits = ['1','3','5'],我们可以写数字,如'13','551', 和'1351315'。返回 可以生成的小于或等于给定整数n的正整数的个数
分析
一道难度较大的动动态规划题目。从题目中我们知道数组不包含数字0.因此我们只要计算使用 digits 的数值能够覆盖多少个数字即可。
我们可以轻易得知:个数与数的位数和每一位数上的数字有关。因此也可以理解为这道题目属于数位方向的动态规划题目。
对应的,我们可以使用记忆化搜索解答本道题目。因此可以得到以下的步骤:
- 将数字 n 转化为数组nums,那么 nums[1]是最低位,nums[len]为最高位;
- dfs(pos,lead,limit)的答案为 dfs(len,1,true)。
总结
特别困难的一道动态规划题目。说实话,我也是看了题解才有一定的思路。原因上来说,本人对于数位指点点掌握的不是特别多,再加上涉及到动态规划。想要解答这道题目,需要有一定的算法基础,尤其是比较偏小众的数位DP知识。
这道题目被力扣归类为hard难度,对于一般的算法同学,特别是刚刚学习算法的同学来说,建议不用花太多的时间在这道题目上。
解题证明
附件
1.[数位DP](数位 DP - OI Wiki (oi-wiki.org))