Leetcode 第 121 场双周赛 Problem D 统计强大整数的数目(Java + 记忆化搜索的数位 DP 模板 + 特判)

文章目录

  • 题目
  • 思路
    • Java + 记忆化搜索的数位 DP 模板 + 特判
    • 第 1 步:
    • 第 2 步:
    • 第 3 步:
  • 复杂度
  • Code

题目

  • Problem: 100163. 统计强大整数的数目
  • 给你三个整数 start ,finish 和 limit 。同时给你一个下标从 0 开始的字符串 s ,表示一个 正 整数。
  • 如果一个 正 整数 x 末尾部分是 s (换句话说,s 是 x 的 后缀),且 x 中的每个数位至多是 limit ,那么我们称 x 是 强大的 。
  • 请你返回区间 [start…finish] 内强大整数的 总数目 。
  • 如果一个字符串 x 是 y 中某个下标开始(包括 0 ),到下标为 y.length - 1 结束的子字符串,那么我们称 x 是 y 的一个后缀。比方说,25 是 5125 的一个后缀,但不是 512 的后缀。
  • 1 <= start <= finish <= 10 ^ 15
  • 1 <= limit <= 9
  • 1 <= s.length <= floor(log10(finish)) + 1
  • s 数位中每个数字都小于等于 limit 。
  • s 不包含任何前导 0 。

思路

Java + 记忆化搜索的数位 DP 模板 + 特判

第 1 步:

  • 根据题意可以想到"记忆化搜素的数位 DP 模板",

第 2 步:

  • 计算 [0, finish] - [0, start-1],将其置为 maxNum,
  • 将 maxNum 中超过 s 的前面位 sChar 取出来,其可以直接套用"记忆化搜索的数位 DP 模板",
  • 注意套用模板时,每一位的上限为 limit,它可能小于 sChar[curIndex],如果这样后面也是随便,

第 3 步:

  • 最后结果加上 0+s 的可能性,
  • 判断是否 DP 中是否取了不能取的 sChar+s,是则减去

复杂度

时间复杂度:

时间复杂度: O ( l i m i t ∗ l o g 10 ( f i n i s h ) ) O(limit * log10(finish)) O(limitlog10(finish))

空间复杂度:

空间复杂度: O ( l o g 10 ( f i n i s h ) ) O(log10(finish)) O(log10(finish))

Code

class Solution {/*** Java + 记忆化搜索的数位 DP 模板 + 特判* 第 1 步:* 根据题意可以想到"记忆化搜素的数位 DP 模板",* ** 第 2 步:* 计算 [0, finish] - [0, start-1],将其置为 maxNum,* 将 maxNum 中超过 s 的前面位 sChar 取出来,其可以直接套用"记忆化搜素的数位 DP 模板",* 注意套用模板时,每一位的上限为 limit,它可能小于 sChar[curIndex],如果这样后面也是随便,* * 第 3 步:* 最后结果加上 0+s 的可能性,* 判断是否 DP 中是否取了不能取的 sChar+s,是则减去* 时间复杂度:O(limit * log10(finish)),空间复杂度:O(log10(finish))*/public long numberOfPowerfulInt(long start, long finish, int limit, String s) {// 转化为 [0, finish] - [0, start-1]return doNumberOfPowerfulInt(finish, limit, Long.parseLong(s), s)- doNumberOfPowerfulInt(start - 1, limit, Long.parseLong(s), s);}/*** 求出 [0, maxNum] 的结果*/private long doNumberOfPowerfulInt(long maxNum, int limit, long sLong, String s) {if (sLong > maxNum) {return 0;}// 将 maxNum 中超过 s 的前面位 sChar 取出来,其可以直接套用"记忆化搜素的数位 DP 模板"sChar = (maxNum + "").substring(0, (maxNum + "").length() - s.length()).toCharArray();int m = sChar.length;// 记忆化搜索:超过 s 的前面位memo = new long[m];// 初始化,-1 表示没有计算过Arrays.fill(memo, -1);// 记忆化搜素的数位 DP 模板,注意 0+s 可能可以long res = recursionDigitDP(0, limit, true, false) + 1;// s 大于 maxNum 对应的位置,sChar 均不大于 limit,此时 DP 中取了不能取的 sChar+sif (checkNotEquals(maxNum, limit, sLong, s)) {res--;}System.out.println("res:" + res);return res;}private boolean checkNotEquals(long maxNum, int limit, long sLong, String s) {String maxNumStr = maxNum + "";long sLenMaxNum = Long.parseLong(maxNumStr.substring(maxNumStr.length() - s.length()));// s 大于 maxNum 对应的位置if (sLong > sLenMaxNum) {for (int i = 0; i < maxNumStr.length() - s.length(); i++) {if (maxNumStr.charAt(i) - '0' > limit) {return false;}}// sChar 均不大于 limitreturn true;}return false;}private char sChar[];private long memo[];/*** 数位 DP 模板:记忆化搜索获取合法数字的个数* @param curIndex 从 i 位开始填数字* @param isLimit 前面填写的数字是否与 sChar 对应上,如果为 true 当前最大为 int(sChar[i]),否则当前最大为 limit* @param isNum 前面是否填写过数字(即处理前导零用),如果为 true 当前可以从 0 开始,否则可以 跳过 或 从 1 开始* @return 返回合法数字的个数*/private long recursionDigitDP(int curIndex, int limit, boolean isLimit, boolean isNum) {/*** 仅有此位置最终定义是否合法* isNum 为 true 表示得到了一个合法数字*/if (curIndex == sChar.length) {return isNum ? 1 : 0;}// isLimit 为 true(前面与 sChar 一样)以及 isNum 为 false(前面全没有填)仅有一种情况,不需要记忆化if (!isLimit && isNum && memo[curIndex] != -1) {return memo[curIndex];}long res = 0;// isNum:前面是否填写过数字(即处理前导零用),可以跳过当前数位if (!isNum) {res = recursionDigitDP(curIndex + 1, limit, false, false);}/*** 判断最大值* isLimit:前面填写的数字是否与 sChar 对应上,如果为 true 当前最大为 int(sChar[i]),否则当前最大为 limit(否则就超过 n 啦)*/int up = isLimit ? Math.min(sChar[curIndex] - '0', limit) : limit;// 枚举要填入的数字 d,isNum:如果为 true 当前可以从 0 开始,否则可以 跳过 或 从 1 开始for (int d = isNum ? 0 : 1; d <= up; d++) {// 由于最大值可能小于 sChar[curIndex],如果这样后面也是随便选因此返回 falseres += recursionDigitDP(curIndex + 1, limit, isLimit && d == up && up == sChar[curIndex] - '0', true);}// 记忆化入数组if (!isLimit && isNum) {memo[curIndex] = res;}return res;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/604016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

postman设置下载文件大小限制

问题 本地写了一个下载文件的接口&#xff0c;调用postman测试的时候&#xff0c;小文件可以&#xff0c;但时大文件就会报错&#xff0c;postman提示&#xff1a; 解决方案 点击postman的设置按钮&#xff0c;点击【Settings】&#xff0c;在打开的弹窗中选择【General】Tab…

三菱plc学习入门(二,三菱plc指令,触点比较,计数器,交替,四则运算,转换数据类型)

今天&#xff0c;进行总结对plc的学习&#xff0c;下面是对plc基础的学习&#xff0c;希望对读者有帮助&#xff0c;欢迎点赞&#xff0c;评论&#xff0c;收藏&#xff01;&#xff01;&#xff01; 目录 触点比较 当数据太大了的时候&#xff08;LDD32位&#xff09; CMP比…

1874_曲轴位置传感器

Grey 全部学习内容汇总&#xff1a; GitHub - GreyZhang/g_ECU_hacking: some learning notes about ECU(engine control unit) hacking. 1874_曲轴位置传感器 功能描述 综述 发动机控制处理中&#xff0c;曲轴位置传感器是非常关键的一个信息。这里先从基本的功能上&…

如何设计企业级业务流程?学习华为的流程六级分类经验

业务流程管理&#xff08;BPM&#xff09;是一种系统化的方法&#xff0c;用于分析、设计、执行、监控和优化组织的业务流程&#xff0c;以实现预期的目标和价值。业务流程管理中&#xff0c;流程的分级方法有多种&#xff0c;常见的有以下几种&#xff1a; APQC的流程分级方法…

【Verilog】基于Verilog的DDR控制器的简单实现(一)——初始化

在FPGA中&#xff0c;大规模数据的存储常常会用到DDR。为了方便用户使用&#xff0c;Xilinx提供了DDR MIG IP核&#xff0c;用户能够通过AXI接口进行DDR的读写访问&#xff0c;然而MIG内部自动实现了许多环节&#xff0c;不利于用户深入理解DDR的底层逻辑。 本文以美光(Micro…

(leetcode)Z字形变换 -- 模拟算法

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 题目链接 . - 力扣&#xff08;LeetCode&#xff09; 输入描述 string convert(string s, int numRows)&#xff0c;输入一个字符串s&#xff0c;以及一个行数numRows&#xff0c;将字符串按照这个行数进行Z字形排列&…

vue项目接入滑动验证码

前言 本文教你基于Node.js环境&#xff0c;在vue项目中如何接入KgCapctah。 准备工作 访问凯格行为验证码官网&#xff0c;注册账号后登录控制台&#xff0c;访问“无感验证”模块&#xff0c;申请开通后系统会分配给应用一个唯一的AppId、AppSecret。凯格提供后端SDK来校验…

Python 面向对象知识点补充

Python 面向对象知识点补充 【一】Mixins机制 【1】概念 Mixins&#xff1a;是一种在面向对象编程中&#xff0c;通过组合多个类的特称来创建一个新类的技术核心机制&#xff1a;就是在多继承的背景下尽可能地提升多继承的可读性通过命名规范来满足人的思维习惯&#xff08;…

Java:File类详解

文章目录 1、概述2、创建File实例3、常用方法3.1 获取功能的方法3.2 绝对路径和相对路径3.3 判断功能的方法3.4 创建删除功能的方法3.5 文件过滤功能的方法 4、文件夹的遍历5、综合练习5.1 创建文件夹5.2 查找文件&#xff08;不考虑子文件夹&#xff09;5.3 查找文件&#xff…

一些数字设计及验证的笔试题(6)

一些数字设计及验证的笔试题汇总&#xff0c;仅供参考。 文章目录 一、什么是亚稳态&#xff1f;如何改善&#xff1f; 二、C语言下列关系符号中&#xff0c;优先级最低的是哪个&#xff1f; 三、下面哪种不属于Vim编辑器的工作模式&#xff1f; 四、在以下的哪个timescale…

python爬虫,简单的requests的get请求,百度搜索实例

1、百度搜索实例 import requests url https://www.baidu.com/s? # key_word 迪丽热巴 key_word input(输入搜索内容&#xff1a;) headers {User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537…

来瞅瞅Java 11都有啥新特性

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff01;今天小黑要和咱们聊聊Java 11&#xff0c;这个在Java发展史上占有一席之地的版本。说起Java&#xff0c;咱们都知道&#xff0c;它是一门历史悠久又持续发展的编程语言。Java不仅因其“一次编写&#xff0c;到处…

Sentinel限流熔断

官网&#xff1a;https://sentinelguard.io/zh-cn/docs/introduction.html github文档&#xff1a;https://github.com/alibaba/Sentinel/wiki Sentinel 是一款面向分布式服务架构的轻量级流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从流量控制、 熔断降级 、系…

百度地图打点性能优化(海量点、mapv)

文章目录 百度地图打点性能优化&#xff08;海量点、mapv&#xff09;原因优化方法数据获取方面页面加载方面 参考资料 百度地图打点性能优化&#xff08;海量点、mapv&#xff09; 原因 在百度地图api中&#xff0c;默认的点是下图的红点 而这种点位比较多的时候&#xff0c…

61、python - 手写卷积、bn、池化、全连接、激活、ResBlock

这篇算是一个总结,之前的原理部分在介绍各个算法时候,已经加入了每个算法的代码编写介绍。 给出的示例是用 python 语法来实现的,也是实现的最基础的版本,这也是我们手写算法的初衷:不调用其他的三方库,从最基础的手写算法开始,一步步完成算法实现和性能优化,这样可以…

ElasticSearch学习笔记-SpringBoot整合Elasticsearch7

项目最近需要接入Elasticsearch7&#xff0c;顺带记录下笔记。 Elasticsearch依赖包版本 <properties><elasticsearch.version>7.9.3</elasticsearch.version><elasticsearch.rest.version>7.9.3</elasticsearch.rest.version> </propertie…

Windows找不到文件‘chrome‘,请确定文件名是否正确后,再试一次。

本文主要记录遇到vscode运行HTML文件提示&#xff1a; Windows找不到文件‘chrome‘&#xff0c;请确定文件名是否正确后&#xff0c;再试一次。问题的解决办法。 目录 一、打开设置 二 、搜索Live Server Config &#xff08;1&#xff09;安装Live Server插件 &#xff0…

如何使用gflags.exe查看内存来源

使用 gflags.exe 工具并不能直接查看内存的来源&#xff0c;即它不能告诉你某块内存是在哪个函数调用或代码行中分配的。然而&#xff0c;gflags 可以结合其他调试工具帮助你检测和分析内存问题&#xff0c;如内存泄漏、堆溢出等。 例如&#xff0c;如果你想追踪某个进程的内存…

asp网站代码层面实现防cc攻击

CC主要是用来攻击页面的.大家都有这样的经历&#xff0c;就是在访问论坛时&#xff0c;如果这个论坛比较大&#xff0c;访问的人比较多&#xff0c;打开页面的速度会比较慢&#xff0c;对不?!一般来说&#xff0c;访问的人越多&#xff0c;论坛的页面越多&#xff0c;数据库就…

Unity ab包如何加密

「ab包」全称为 AssetBundle &#xff0c;是Unity提供的一种资源存储压缩包。其中储存了游戏的资源&#xff0c;如图片、模型、纹理、音视频、代码等文件。 由于ab包具有灵活储存、支持热更、包体较小且便于管理等优势&#xff0c;已经成为了市面上主流的游戏资源压缩方式。 …