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

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; } }
http://www.jsqmd.com/news/353265/

相关文章:

  • 从CDF到PDF:深入理解概率分布的核心工具
  • 使用n8n构建企业级智能客服RAG知识库:从零搭建到生产环境部署
  • 政务云Docker集群国产化改造失败率高达67%?资深架构师亲授5个不可跳过的国产中间件对接细节
  • 智能客服系统数据集构建实战:从数据清洗到模型训练全流程解析
  • ChatGPT用不了?实战指南:自建代理与API容灾方案
  • 企业微信智能客服的AI辅助开发实战:从架构设计到性能优化
  • 【车载系统调试革命】:Docker容器化调试的5大实战陷阱与避坑指南(20年嵌入式老兵亲测)
  • Docker镜像层存储失控真相(2024生产环境血泪复盘):从127GB膨胀到8GB的压缩全路径
  • 从零构建RISC-V蓝牙设备:CH5xx GPIO实战避坑指南
  • Docker中运行Phi-3-mini为何总OOM?——从ulimits、shm-size到--gpus参数的11项硬核配置校验清单
  • Docker存储安全漏洞全景扫描,7类未授权挂载风险曝光,DevSecOps团队紧急自查清单
  • 【仅限头部云厂商内部流出】Docker监控效能评估白皮书(含17项SLI/SLO定义标准+4类典型误报归因模型)
  • Langflow实战指南:可视化工作区与Playground高效开发技巧
  • Docker如何让智慧农场效率提升47%?农业物联网部署的5个致命误区与破解公式
  • 大数据毕设旅游系统:从数据采集到可视化分析的全链路技术实践
  • Qt项目毕设从零起步:新手避坑指南与核心架构实践
  • 机器学习Matlab毕设论文实战指南:从算法选型到可复现结果的完整技术路径
  • Docker Compose v2.23+量子服务发现配置(DNS负载均衡+健康探测零抖动),错过本次更新将无法适配2025年CNCF认证标准
  • D.二分查找-二分答案-求最大——2576. 求出最多标记下标
  • Docker容器启动慢如蜗牛?揭秘CPU绑定、内存预分配与IO调度的5大工业级加速方案
  • 国产操作系统+Docker组合部署踩坑大全,华为欧拉、统信UOS双平台避坑清单
  • 计算机网络专科毕业设计:从零实现一个轻量级HTTP代理服务器(含并发与安全考量)
  • ChatGPT Atlas浏览器下载与AI辅助开发实战:从原理到生产环境部署
  • Cesium贴模型播放视频:性能优化与实战避坑指南
  • Python DeepSeek 智能客服实战:从零构建 AI 辅助开发框架
  • ComfyUI视频模型入门指南:从零搭建到实战避坑
  • Docker多架构镜像构建避坑清单:5个99%工程师踩过的坑,第3个导致CI/CD全线崩溃?
  • Docker边缘容器化部署全链路解析(K3s+EdgeX+OTA热更新深度拆解)
  • ChatTTS 语音合成实战:如何正确处理多音字与停顿问题
  • GP8101 PWM转0-5V/10V模拟电压模块原理图设计,已量产