解题思路:数位DP。dp数组为dp[pos][sum]表示当前位以下还有pos个可变位并且当前位以及它的最高位出现了sum个1的dp值。因为数的取值为2^31所以,数组开dp[10][10]就够了。

数位DP入门博客:

https://www.luogu.com.cn/blog/virus2017/shuweidp#

https://blog.csdn.net/qq_25957237/article/details/102877820

 1 class Solution:
2 def dfs(self,pos,one_sum,limit):
3 #如果剩余可变位为0,范围当前数所有的one_sum,即当前状态的之前位有多少个1了
4 if pos==0:
5 return one_sum
6 #如果没有受限并且dp值被记录过了,直接返回状态值
7 if not limit and self.dp[pos][one_sum]!=-1:
8 return self.dp[pos][one_sum]
9 up = 9
10 if limit:
11 up = self.nums[pos-1]
12 ans =0
13 for i in range(up+1):
14 #状态转移方程:如果当前位是1,那么next_one_sum +=1
15 if i==1:
16 nxt_one_sum = one_sum + 1
17 else:
18 nxt_one_sum = one_sum
19 #搜索下一位,下一个状态的limit的由当前limit控制并且当前的值真的到了当前位的限制值.
20 #以365为例,搜索0??,1??,2??的limit都为false,只有当搜索3??的时候才继续为真.
21 ans+= self.dfs(pos-1,nxt_one_sum, limit and i==self.nums[pos-1])
22
23 if not limit:#如果没有限制,说明下次再访问dp[pos][one_sum]的状态是一样的,记忆化
24 self.dp[pos][one_sum] = ans
25 return ans
26
27 def solve(self,n):
28 self.nums = []
29 while n:
30 self.nums.append(n%10)
31 n//=10
32 #自高位向低位进行数位dp,因为从高位开始dp,因此limit为真
33 return self.dfs(len(self.nums),0,True)
34 def countDigitOne(self, n):
35 # dp[pos][sum]表示当前位以下还有pos个可变位并且当前位以及它的最高位出现了sum个1的dp值
36 #比如对于356这个数,0??的dp值应该与2??dp值一样为dp[2][0],但是与3??的dp值不同,因为3是最高位,受到limit的制约
37 #它不能保存dp值,除非再添加一个limit的维度(dp[10][10][2]),1??的dp值为dp[2][1]
38 self.dp = [[-1]*10 for _ in range(10)]
39 cnt = self.solve(n)
40 #print(self.dp[2][0])
41 #print(self.dp[2][1])
42 return cnt
43
44
45
46 c = Solution()
47 #n = 302
48 z = c.countDigitOne(365)
49 print(z)

剑指Offer43:1~n整数中1出现的次数(数位DP)的更多相关文章

  1. 剑指 Offer 56 - II. 数组中数字出现的次数 II + 位运算

    剑指 Offer 56 - II. 数组中数字出现的次数 II Offer_56_2 题目详情 解题思路 java代码 package com.walegarrett.offer; /** * @Au ...

  2. 剑指 Offer 56 - I. 数组中数字出现的次数 + 分组异或

    剑指 Offer 56 - I. 数组中数字出现的次数 Offer_56_1 题目描述 解题思路 java代码 /** * 方法一:数位方法 */ class Offer_56_1_2 { publi ...

  3. 剑指 Offer 43. 1~n 整数中 1 出现的次数 + 数位模拟 + 思维

    剑指 Offer 43. 1-n 整数中 1 出现的次数 Offer_43 题目描述 题解分析 java代码 package com.walegarrett.offer; /** * @Author ...

  4. 剑指offer系列57---整数中1出现的次数

    [题目]求出1~n的整数中1出现的次数.(10进制) package com.exe11.offer; /** * [题目]求出1~n的整数中1出现的次数. * @author WGS * */ pu ...

  5. 剑指 Offer 56 - II. 数组中数字出现的次数 II

    题目描述 在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次.请找出那个只出现一次的数字. 示例1: 输入:nums = [3,4,3,3] 输出:4 示例2: 输入:nums = ...

  6. 剑指 Offer 56 - I. 数组中数字出现的次数

    题目描述 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是\(O(n)\),空间复杂度是\(O(1)\). 示例1: 输入:nums ...

  7. 《剑指offer》面试题32----从1到n整数中1出现的次数

    题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次. 解法一:不考虑时间效率的解法(略) ps ...

  8. 剑指Offer - 九度1373 - 整数中1出现的次数(从1到n整数中1出现的次数)

    剑指Offer - 九度1373 - 整数中1出现的次数(从1到n整数中1出现的次数)2014-02-05 23:03 题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直 ...

  9. 剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数)

    剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数) 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https:// ...

  10. Go语言实现:【剑指offer】整数中1出现的次数(从1到n整数中1出现的次数)

    该题目来源于牛客网<剑指offer>专题. 求出1 ~ 13的整数中1出现的次数,并算出100 ~ 1300的整数中1出现的次数?为此他特别数了一下1 ~ 13中包含1的数字有1.10.1 ...

随机推荐

  1. 《Kali渗透基础》04. 主动信息收集(一)

    @ 目录 1:主动信息收集 2:发现 3:二层发现 3.1:arping 3.2:nmap 3.3:netdiscover 3.4:Scapy 4:三层发现 4.1:ping 4.2:Scapy 4. ...

  2. Redis系列21:缓存与数据库的数据一致性讨论

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  3. (null) entry in command string: null chmod 0644

    在WIndows操作系统中本地运行spark程序,报以下错误: ....(null) entry in command string: null chmod 0644 ..(后面是目的目录) 解决方法 ...

  4. nmcli 命令设置网络

    nmcli 命令设置网络 设置静态 IP 地址 sudo nmcli connection modify "连接名称" ipv4.addresses IP地址/子网掩码 设置网关 ...

  5. Vue.js 官方脚手架 create-vue 是怎么实现的?

    Vue.js 官方脚手架 create-vue 是怎么实现的? 摘要 本文共分为四个部分,系统解析了vue.js 官方脚手架 create-vue 的实现细节. 第一部分主要是一些准备工作,如源码下载 ...

  6. 2-MySQL基本语法

    上文说到,数据库的安装和连接,接下来将给大家讲解MySQL数据库的基本语法及数据的类型 1.基本语法 (1).查看当前所有数据库 : show databases; (2).创建数据库 create ...

  7. git升级编译安装

    一.删除旧版本git 方法一. yum remove git -y (centos环境) apt-get remove git -y (Ubuntu环境) 方法二. which git [root@p ...

  8. 一个vuepress配置问题,引发的js递归算法思考

    前言 这两天在尝试用语雀+ vuepress + github 搭建个人博客. 小破站地址 :王天的 web 进阶之路 语雀作为编辑器,发布文档推送 github,再自动打包部署,大概流程如下. 问题 ...

  9. nginx防盗链+flv.js拉流地址防盗

    需要此版本nginx的私信留邮箱,支持http-flv,支持rtmp,支持secure_link nginx.conf配置: c#后端生成链接 结果:

  10. dijkstra算法(朴素 + 堆优化)

    dijkstra算法的大题思路是通过n - 1次迭代,每次迭代把一个点距汇点的最短路确定,当n - 1次循环过后所有点的最短路都已经确定 注意:dijkstra算法只适用于没有负权边的单源最短路 以下 ...