当前位置: 首页 > news >正文

LeetCode每日一题——902. 最大为 N 的数字组合

LeetCode每日一题系列

题目:902. 最大为 N 的数字组合
难度:困难


文章目录

  • LeetCode每日一题系列
  • 题目
  • 示例
  • 思路
  • 题解


题目

给定一个按 非递减顺序 排列的数字数组 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

思路

数位dp:

  1. 定义状态:我们用 dp[i][0]表示由 digits构成且小于n 的前 i 位的数字的个数,dp[i][1] 表示由 digits构成且等于 n 的前 i 位的数字的个数,可知 dp[i][1] 的取值只能为0 和 1。

  2. n表示给定数字最大值,d表示digits中的数字,n的前i位组成的数字为n[i],这里会遇到几种情况:
    1、当i>1时,任意digits中的d都小于等于s[:i],这一情况下满足条件的数量为len(digits)
    2、当d<n[i-1],我们任意再向后面加一位都满足条件,这一情况满足条件的数量为dp[i-1][0] * len(digits)
    3、当d=n[i-1],我必须向后加一个小于n[i]的才满足条件,这一情况满足条件的数量为dp[i-1][0]*digits中小于n[i]的值

  3. 我们初始将dp[0][1]设为1,遍历到后面如果发现digits中不含有某个n[i],再将dp[i][1]设置为1

  4. 设 C[i]表示数组 digits 中小于 n 的第 i 位数字的元素个数,综上所述,dp的状态转移方程为:
    在这里插入图片描述

题解

class Solution:
    def atMostNGivenDigitSet(self, digits: List[str], n: int) -> int:
        m = len(digits)
        s = str(n)
        k = len(s)
        dp = [[0, 0] for _ in range(k + 1)]
        # 设置初始状态
        dp[0][1] = 1
        # 遍历n
        for i in range(1, k + 1):
        	# 遍历digits
            for d in digits:
            	# digits中存在n[i]
                if d == s[i - 1]:
                    dp[i][1] = dp[i - 1][1]
                # d小于n[i-1],累加上dp[i-1][1],属于当d=n[i-1],我必须向后加一个小于n[i]的才满足条件的情况
                elif d < s[i - 1]:
                    dp[i][0] += dp[i - 1][1]
                else:
                    break
            # 当i>1,累加上所有情况即可
            if i > 1:
                dp[i][0] += m + dp[i - 1][0] * m
        # 返回最后一位dp[k][0]和dp[k][1]的和即可
        return sum(dp[k])

相关文章:

  • Java学习--JDBC
  • C++中GDAL批量创建多个栅格图像文件并批量写入数据
  • 基于maven的spring项目实现登录注册(SSM)
  • 【C++】动态内存管理
  • 波士顿动力再惊艳!机器人大秀男团舞,举手投足人味满满,多次转卖后展示新标签...
  • Python 代码托管到码云平台,原来这么简单
  • 【MATLAB教程案例26】图像特征点提取算法matlab仿真与分析——sift,surf,kaze,corner,BRISK等
  • 前端深拷贝与浅拷贝(附实现方法)
  • C#工业生产线MES系统,源代码分享
  • 2022软考高项十大领域知识整理(四)-人力资源管理、干系人管理、采购管理
  • 企业级低代码平台Jeecgboot3.4.2及3.4.3版本新功能介绍
  • SQL SERVER Sequence Number 序列号
  • 【Web实战-Tomcat-Servlet-Thymeleaf -JDBC-MySQL】浏览器页面显示数据库数据(水果库存系统)
  • 【超好懂的比赛题解】2022CCPC四川省赛 个人题解
  • Pytest如何执行txt格式的文本测试
  • Google 是如何开发 Web 框架的
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • Angular 响应式表单 基础例子
  • Angularjs之国际化
  • CSS盒模型深入
  • css属性的继承、初识值、计算值、当前值、应用值
  • express如何解决request entity too large问题
  • Laravel5.4 Queues队列学习
  • React 快速上手 - 07 前端路由 react-router
  • Sass Day-01
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Travix是如何部署应用程序到Kubernetes上的
  • Zepto.js源码学习之二
  • 讲清楚之javascript作用域
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 容器服务kubernetes弹性伸缩高级用法
  • 使用API自动生成工具优化前端工作流
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 线上 python http server profile 实践
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 在weex里面使用chart图表
  • 字符串匹配基础上
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • UI设计初学者应该如何入门?
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #100天计划# 2013年9月29日
  • #1015 : KMP算法
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • (2)nginx 安装、启停
  • (6)添加vue-cookie
  • (JS基础)String 类型
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (过滤器)Filter和(监听器)listener
  • (十)c52学习之旅-定时器实验
  • (十六)一篇文章学会Java的常用API
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (四)鸿鹄云架构一服务注册中心