news 2026/9/14 13:09:17

D.二分查找-二分答案-求最大——1898. 可移除字符的最大数目

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
D.二分查找-二分答案-求最大——1898. 可移除字符的最大数目

题目链接:1898. 可移除字符的最大数目(中等)

算法原理:

此题的题意跟下面这题基本一模一样👇,只不过之前的求最小,这个是求最大

D.二分查找-二分答案-求最小——3639. 变为活跃状态的最小时间

解法:二分查找

96ms击败40.00%

时间复杂度O(Nlogn)

①目标变量:依次移除下标数

②目标条件:在保证p是否还是剩下子串的子序列的前提下,尽量多移除下标

③转换逻辑:移除前mid个下标对应的字符后,p是否还是剩下子串的子序列

具体步骤:

①确定边界:

left:0,最少就是一个都不移除

right:removable.length,最多就是把removable数组中的下标全移除

②确定二分模型:

移除下标数↑ p是剩余子串的子序列的概率↓ 呈负相关单调,由于是找最大移除下标数,因此采用最右端点模型

③check方法设计:

如果移除了mid个下标,如果p还是剩下子串的子序列就返回true,mid不动地方,否则就是移除多了,需要向左调整,这里我们采用标记数组,如果s数组中的字符被移除就标记为true,遍历时从左向右依次检查,如果未被移除,且能和p中字符对应,就相应指针往后挪,继续检查,当指针恰好把p走完,说明还有p的这个子序列

答疑

Q1:既然是一一对应检查,我把s和p都存进顺序表检查不可以吗?

有的小伙伴写check方法时可能会想到用顺序表,给s和p分别创建一个顺序表,利用Java自带的ArrayList移除中间元素后,后续元素会自动向前拼接的特性来判断s剩余字符串是否还存在子序列p,相关代码放下面了,但这有个致命错误,那就是下标偏移错误,举个例子👇

假设原始 s = "abcde"(下标 0-4),r = [2, 3](要移除原始下标 2 和 3,对应字符 'c' 和 'd')
第一步:tmp.remove(2) → tmp 变成 ["a","b","d","e"](原始 'd' 现在在 tmp 的下标 2 位置)
第二步:tmp.remove(3) → 你想删原始下标 3 的 'd',但现在 tmp 的下标 3 是 'e',结果删成了 'e',完全错了

Java代码:

class Solution { public int maximumRemovals(String s, String p, int[] r) { int left=0,right=r.length; while(left<right){ int mid=left+(right-left+1)/2; if(!check(mid,s,p,r)) right=mid-1; else left=mid; } return left; } //移除前mid个下标对应字符后,子序列还有p就返回true private boolean check(int mid,String s, String p, int[] r){ int n=s.length(); boolean[] removed=new boolean[n]; for(int i=0;i<mid;i++) removed[r[i]]=true; int pindex=0; for(int i=0;i<n&&pindex<p.length();i++) if(!removed[i]&&s.charAt(i)==p.charAt(pindex)) pindex++; return pindex==p.length(); } }
class Solution { //错误的示范代码 private static List<Character> listp=new ArrayList<>(); private static List<Character> lists=new ArrayList<>(); public int maximumRemovals(String s, String p, int[] r) { for(char c:p.toCharArray()) listp.add(c); for(char c:s.toCharArray()) lists.add(c); int left=0,right=r.length; while(left<right){ int mid=left+(right-left+1)/2; if(!check(mid,r)) right=mid-1; else left=mid; } //个数=下标+1 return left+1; } //移除前mid个下标对应字符后,子序列还有p就返回true private boolean check(int mid,int[] r){ List<Character> tmp=new ArrayList<>(lists); int index=0; for(int i=0;i<mid;i++) tmp.remove(r[i]); for(char c:tmp) if(c==listp.get(index)) index++; return index==listp.size()-1; } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 23:09:06

基于STM32的毕业设计开源项目:从选型到落地的完整技术路径

基于STM32的毕业设计开源项目&#xff1a;从选型到落地的完整技术路径 摘要&#xff1a;许多高校学生在完成基于STM32的毕业设计时&#xff0c;常面临项目同质化、代码结构混乱、缺乏工程规范等痛点。本文系统梳理典型应用场景下的技术选型逻辑&#xff0c;对比主流开发框架&am…

作者头像 李华
网站建设 2026/9/13 7:09:26

ChatGPT Windows桌面版安装包深度解析:从原理到本地化部署实战

背景痛点&#xff1a;网页版在 Windows 上的“水土不服” 很多开发者第一次用 ChatGPT 网页版时&#xff0c;都会遇到“三高一低”的尴尬&#xff1a; 高网络依赖&#xff1a;每次刷新都要重新拉取 3 MB 以上的 JS 资源包&#xff0c;弱网环境直接白屏。高内存占用&#xff1…

作者头像 李华
网站建设 2026/8/21 19:49:53

ChatGPT PreAuth PlayIntegrity Verification Failed 问题解析与解决方案

ChatGPT PreAuth PlayIntegrity Verification Failed 问题解析与解决方案 背景介绍&#xff1a;PreAuth 与 PlayIntegrity 在 API 调用中的角色 如果你最近把 ChatGPT 官方 SDK 升级到 1.x&#xff0c;大概率会在 Logcat 或终端里撞见一行刺眼的红色报错&#xff1a; ChatGP…

作者头像 李华
网站建设 2026/9/8 2:51:01

智能客服Agent开发实战:基于AI辅助的架构设计与性能优化

智能客服Agent开发实战&#xff1a;基于AI辅助的架构设计与性能优化 1. 背景与痛点&#xff1a;为什么传统客服脚本撑不住&#xff1f; 做ToB SaaS的朋友都懂&#xff0c;&#xff1a;客服脚本一旦超过200条&#xff0c;维护就像拆炸弹——改一行&#xff0c;炸一片。 体验过的…

作者头像 李华
网站建设 2026/8/21 19:49:57

AI 辅助开发实战:基于无人机毕业设计的智能任务调度系统构建

1. 学生项目常见痛点&#xff1a;为什么“能飞”≠“能毕业” 做无人机毕设&#xff0c;很多同学第一步就卡在“飞起来”到“飞得稳”之间。实验室里常见的一幕&#xff1a;飞机刚离地半米就左右飘&#xff0c;PID 调参调得怀疑人生&#xff1b;好不容易稳了&#xff0c;再加个…

作者头像 李华
网站建设 2026/9/8 2:47:10

Chatbot Evaluation的困境与突破:如何解决上下文理解错误问题

Chatbot Evaluation的困境与突破&#xff1a;如何解决上下文理解错误问题 背景&#xff1a;当“答非所问”不是模型笨&#xff0c;而是我们测得不对 过去两年&#xff0c;我陆续给三款客服机器人做上线前评估。无论BLEU还是人工打分&#xff0c;报告都“漂亮”&#xff0c;可一…

作者头像 李华