leetcode 1416. Restore The Array(恢复数组)

news/2024/11/6 13:51:20/

在这里插入图片描述

一台打印机没有把空格打印出来,以至于不知道打印出的 s 中到底有哪些数字。
现在知道数字的取值范围在1 ~ k, 数字开头不能是0.
返回可能的数字个数。取模109+7.

思路:

DP

假设dp[ i ]为 i ~ n位的s 所能组成的数字组合数。

从右到左遍历,说下为什么是从右到左。
因为数字要连续出现的,以“1317"为例,如果从左到右,比如现在遍历到 j = 2, 即第2个1,
而“131”这个数字中,如果取了“13”,那么和j=3的“7”组合时,就不连续了,变成了"13"和“7",这个是不好控制的。

下面以Example3的"1317"为例来说明。

初始状态,空字符串,个数为1,dp[4]=1,

i = 3, s[ i ] = “7”,7 < k, 7与空字符串组合,那么需要知道空字符串有多少种可能(dp[4] )。
这时dp[ 3 ] += dp [ 4 ].

i = 2, s[2] = “1”,1 < k,
“1”可与“7”组合成[1, 7],也可与空字符串组合成[1], 因此需要知道"7"有多少种可能( dp [ 3 ] ).
这时dp [ 2 ] += dp [ 3 ].

i = 1, s[ i ] = “3”, 3 < k, 可以选择"3"和“17”组合,那么需要知道“17”有多少种可能,
于是有[3, 17] 和 [3, 1, 7]
这时dp [ 1 ] += dp [ 2 ].

也可以选择“31“和”7“组合,31 < k, 那么需要知道"7"有多少种可能。
这时dp [ 1 ] += dp [ 3 ].

最后i = 0, s[0] = “1”, 1 < k, "1"可以和"317"组合,
dp[0] += dp[1]
13 < k , "13“和”17“组合,( [13, 17], [13, 1, 7], [13, 1] )
dp[0] += dp[2]
131 < k, "131"和“7”组合,( [131, 7] )
dp[0] += dp[3]

前提是当前数字 <= k, 如果当前数字 > k, 则进入下一个 i 的遍历。
如果当前s [ i ]为0,也进入下一遍历,因为数字不能是0开头。
最后返回dp[0], 即 0 ~ n-1的组合数。

    public int numberOfArrays(String s, int k) {final int MOD = (int)1e9+7;int n = s.length();int[] dp = new int[n+1]; //dp[i]:i~n的组合个数char[] chs = s.toCharArray();dp[n] = 1;for(int i = n-1; i >= 0; i--) {if(chs[i] == '0') continue; //0开头的不算long sum = 0, num = 0;for(int j = i; j < n; j++) {num = num*10 + (chs[j]-'0');if(num > k) break;sum += dp[j+1];}dp[i] = (int)(sum % MOD);}return dp[0];}

在这里插入图片描述

如果实在不好理解,可以参考下面的流程

初始状态,'': dp[4]=1
i=3,指向s[3]=7
j=3,指向s[3]=7
现在num=7
num (7) < k (2000)
[7 ~ 7] 和 [''] 组合
dp[3] += dp[4]=1
dp[3]=1i=2,指向s[2]=1
j=2,指向s[2]=1
现在num=1
num (1) < k (2000)
[1 ~ 1] 和 [7~ 最后] 组合
dp[2] += dp[3]=1
j=3,指向s[3]=7
现在num=17
num (17) < k (2000)
[1 ~ 7] 和 [''] 组合
dp[2] += dp[4]=2
dp[2]=2i=1,指向s[1]=3
j=1,指向s[1]=3
现在num=3
num (3) < k (2000)
[3 ~ 3] 和 [1~ 最后] 组合
dp[1] += dp[2]=2
j=2,指向s[2]=1
现在num=31
num (31) < k (2000)
[3 ~ 1] 和 [7~ 最后] 组合
dp[1] += dp[3]=3
j=3,指向s[3]=7
现在num=317
num (317) < k (2000)
[3 ~ 7] 和 [''] 组合
dp[1] += dp[4]=4
dp[1]=4i=0,指向s[0]=1
j=0,指向s[0]=1
现在num=1
num (1) < k (2000)
[1 ~ 1] 和 [3~ 最后] 组合
dp[0] += dp[1]=4
j=1,指向s[1]=3
现在num=13
num (13) < k (2000)
[1 ~ 3] 和 [1~ 最后] 组合
dp[0] += dp[2]=6
j=2,指向s[2]=1
现在num=131
num (131) < k (2000)
[1 ~ 1] 和 [7~ 最后] 组合
dp[0] += dp[3]=7
j=3,指向s[3]=7
现在num=1317
num (1317) < k (2000)
[1 ~ 7] 和 [''] 组合
dp[0] += dp[4]=8
dp[0]=8

http://www.ppmy.cn/news/50187.html

相关文章

人工智能包含哪些知识

人工智能是一个广泛的领域&#xff0c;它涉及多个学科和知识领域。以下是人工智能包含的一些知识&#xff1a; 计算机科学&#xff1a;人工智能的发展需要计算机科学中的许多概念和技术&#xff0c;如算法、数据结构、计算机体系结构、计算理论等。 数学&#xff1a;数学在人工…

4、RSA终端指令

RSA总结 加密算法,都是数学知识对称加密(传统加密算法)RSA(三个人的名字)非对称加密(现代加密算法) 原根欧拉函数、欧拉定理(费马小定理)模反元素 m^(e * d) mod n ≡ m迪菲赫尔曼密钥交换RSA算法 RSA: 拆解两个(大)质数的乘积很难!所以RSA想对安全.加密: M ^e % N C解密: C…

java: web应用中不经意的内存泄露

前面有一篇讲解如何在spring mvc web应用中一启动就执行某些逻辑&#xff0c;今天无意发现如果使用不当&#xff0c;很容易引起内存泄露&#xff0c;测试代码如下&#xff1a; 1、定义一个类App package com.cnblogs.yjmyzz.web.controller;import java.util.Date;public cla…

【数据挖掘】5分钟带你了解文本向量化的常见方式

5分钟带你了解文本向量化的常见方式 1. 独特编码模型2. 词袋模型3. TF-IDF模型4. N-gram模型5. Word2Vec模型参考资料文本向量化:将文本信息表示成能够表达文本语义的向量,是 用数值向量来表示文本的语义。 词嵌入(Word Embedding):一种将文本中的词转换成数字向量的方法,…

Elasticsearch REST API 文档管理

文章目录 创建文档路径参数常用查询参数示例响应说明 查询文档路径参数编辑查询参数示例 1响应说明示例2示例3 更新文档路径参数查询参数示例1示例2禁用noop mget 获取多个文档路径参数查询参数请求正文参数说明示例1响应结果示例2 删除文档路径参数查询参数示例1 开放式并发控…

Redis7

Redis之父安特雷兹 Redis7概述 Redis:Remote Dictionary Server(远程字典服务)是完全开源的&#xff0c;使用ANSIC语言编写遵守BSD协议&#xff0c;是一个高性能的Key-Value数据库提供了丰富的数据结构&#xff0c;例如String、Hash、List、Set、SortedSet等等。数据是存在内…

docker离线部署 升级

其它版本linux内核系统或许略有不同 下载docker版本包 https://download.docker.com/linux/static/stable/x86_64/centos部署版本 上传到服务器目录下&#xff0c;解压文件。 tar -xvf docker-XXXXXX.tgz将解压出来的docker文件内容移动到 /usr/bin/ 目录下&#xff0c;该命…

FE_CSS 常见布局技巧

1 巧妙运用浮动元素不会压住文字的特性 float: left; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta ht…