news 2026/6/15 14:03:35

Leetcode 82 每个字符最多出现两次的最长子字符串 | 删掉一个元素以后全为 1 的最长子数组

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Leetcode 82 每个字符最多出现两次的最长子字符串 | 删掉一个元素以后全为 1 的最长子数组

1 题目

3090. 每个字符最多出现两次的最长子字符串

给你一个字符串s,请找出满足每个字符最多出现两次的最长子字符串,并返回该子字符串的最大长度。

示例 1:

输入:s = "bcbbbcba"

输出:4

解释:

以下子字符串长度为 4,并且每个字符最多出现两次:"bcbbbcba"

示例 2:

输入:s = "aaaa"

输出:2

解释:

以下子字符串长度为 2,并且每个字符最多出现两次:"aaaa"

提示:

  • 2 <= s.length <= 100
  • s仅由小写英文字母组成。

2 代码实现

联想

和第三题的框架完全一致,先贴一个leetcode3的解法。

3. 无重复字符的最长子串

class Solution { public: int lengthOfLongestSubstring(string s) { unordered_map<char , int > window ; int left = 0 , right = 0 ; int res = 0 ; while (right < s.size()){ char c = s[right] ; right++; window[c]++; while (window[c] > 1 ){ char d = s[left]; left ++; window[d] --; } res = max (res,right - left); } return res; } };

本题做法:

class Solution { public: int maximumLengthSubstring(string s) { unordered_map<char , int >window; int left = 0 ; int right = 0; int res = 0 ; while (right < s.size()){ char c = s [right ]; right ++; window[c]++; while(window[c] > 2){ char d = s[left]; left ++; window[d]--; } res = max(res , right - left ); } return res; } };

总结

  1. 收缩左边界的核心目的:让滑动窗口[left, right)重新回到无重复字符的状态,这是我们计算最长无重复子串长度的前提。
  2. 收缩左边界的逻辑:从最左侧开始依次移出字符,直到当前重复的字符c的计数满足条件,此时窗口内不再有重复字符。
  3. 整个滑动窗口的策略:右指针扩展窗口找新字符,左指针收缩窗口去重,过程中持续记录窗口的最大长度。


3 题目

1493. 删掉一个元素以后全为 1 的最长子数组

给你一个二进制数组nums,你需要从中删掉一个元素。

请你在删掉元素的结果数组中,返回最长的且只包含 1 的非空子数组的长度。

如果不存在这样的子数组,请返回 0 。

提示 1:

输入:nums = [1,1,0,1]输出:3解释:删掉位置 2 的数后,[1,1,1] 包含 3 个 1 。

示例 2:

输入:nums = [0,1,1,1,0,1,1,0,1]输出:5解释:删掉位置 4 的数字后,[0,1,1,1,1,1,0,1] 的最长全 1 子数组为 [1,1,1,1,1] 。

示例 3:

输入:nums = [1,1,1]输出:2解释:你必须要删除一个元素。

提示:

  • 1 <= nums.length <= 105
  • nums[i]要么是0要么是1

4 代码实现

思考

删掉一个0元素以后最长的全1数组长度,那么如果没有删除,就是一个数组最长,里面有且仅有一个0元素,其余都是1的元素。

思路:维护一个滑动窗口,只含有一个0,这个窗口最长的长度。

根本不需要和题目的操作一样顺着来这个先删除的操作,最后这个窗口的长度减去一就是答案了!

自己写的错误百出的代码

class Solution { public: int longestSubarray(vector<int>& nums) { unordered_map <int , int > window; int left = 0 ; int right = 0 ; int res = 0 ; while (right < nums.size()){ right ++; if (nums[right] == 1 ){ window[1]++; }else{ window[0]++; } while(window[0] == 1){ left ++; if(nums[left] == 1 ){ window[1]--; }else{ window[0]--; } } res = max(res , window[1] - 1); } return res ; } };

首先,明确你的核心需求

你想要实现的功能是:给定一个由 0 和 1 组成的数组,删除最多一个0(也可以不删)后,找到最长的连续 1 的子数组长度。

代码中存在的关键问题

  1. 数组越界问题right++执行后,直接访问nums[right],当right达到nums.size()时,会访问到数组的越界位置,导致程序崩溃。
  2. 收缩窗口的逻辑错误while(window[0] == 1)的条件错误,应该是当窗口内的 0 的数量超过 1 时才收缩窗口(因为题目允许删除最多一个 0)。
  3. 左指针移动后的计数错误:收缩窗口时,先执行left++再访问nums[left],会漏掉对nums[left]初始位置的字符计数修改,导致window的计数不准确。
  4. 结果计算错误res = max(res, window[1] - 1)会错误地将 1 的计数减 1,正确的应该是直接取窗口内的有效长度(或window[1],根据逻辑调整)。

修复后的完整代码

#include <vector> #include <unordered_map> #include <algorithm> using namespace std; class Solution { public: int longestSubarray(vector<int>& nums) { unordered_map<int, int> window; // 键:0或1,值:对应数字在窗口中的出现次数 int left = 0, right = 0; int res = 0; int max_ones = 0; // 记录窗口内1的最大数量 int zero_count = 0; // 窗口内0的数量(也可以用window[0],单独变量更直观) while (right < nums.size()) { int num = nums[right]; right++; // 右指针扩展窗口 // 更新窗口内的计数 if (num == 1) { window[1]++; max_ones = max(max_ones, window[1]); // 记录1的最大数量 } else { window[0]++; zero_count++; } // 当窗口内0的数量超过1时,收缩左边界(因为最多只能删一个0) while (zero_count > 1) { int left_num = nums[left]; left++; // 左指针收缩窗口 // 更新计数 if (left_num == 1) { window[1]--; } else { window[0]--; zero_count--; // 关键:0的数量减1,退出循环的关键 } } // 计算当前窗口的有效长度:窗口长度(right-left)- 1(因为必须删除一个元素,即使是0) // 题目要求是“删除一个元素后”的长度,所以不管有没有0,都要减1 res = max(res, right - left - 1); } return res; } };

代码关键部分解释

  1. 解决数组越界:先取nums[right]的值,再执行right++,避免访问越界的位置。
  2. 收缩窗口的条件:当zero_count > 1时(窗口内有超过 1 个 0),收缩左边界,直到 0 的数量≤1(符合最多删一个 0 的要求)。
  3. 计数更新逻辑:收缩左边界时,先取nums[left]的值,再执行left++,确保计数修改的是当前左指针指向的元素。
  4. 结果计算right - left - 1是删除一个元素后的窗口长度(题目要求必须删除一个元素,即使数组全是 1,也要删一个,比如[1,1,1]的结果是 2)。如果题目允许不删除元素(即最多删一个),则可以调整为max(res, zero_count == 0 ? right - left - 1 : right - left)

测试用例

我们用几个例子验证代码的执行效果:

  • 输入nums = [1,1,0,1]
    • 过程:窗口会包含[1,1,0,1](0 的数量 = 1),有效长度 = 4-1=3,结果为 3。
  • 输入nums = [0,1,1,1,0,1,1,0,1]
    • 有效长度为 5(比如窗口[1,1,1,0,1,1],长度 6-1=5),结果为 5。
  • 输入nums = [1,1,1]
    • 有效长度 = 3-1=2,结果为 2。

自行修正后代码实现

class Solution { public: int longestSubarray(vector<int>& nums) { unordered_map <int , int > window; int left = 0 ; int right = 0 ; int res = 0 ; while (right < nums.size()){ int a = nums[right]; right ++; if (a == 1 ){ window[1]++; }else{ window[0]++; } while(window[0] > 1){ int b = nums[left]; left ++; if(b == 1 ){ window[1]--; }else{ window[0]--; } } res = max(res , right - left - 1); } return res ; } };

测试通过!

小结

好像感受到一些思路了,的确这种题目有固定的模板,也就是通用的解法,按照这个边总结边练习的方式刷题效果好了很多,加油(ง •_•)ง!!!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 18:35:51

告别手动查询:Open-AutoGLM实现社保信息自动化采集的3大核心技巧

第一章&#xff1a;告别手动查询&#xff1a;Open-AutoGLM赋能社保信息自动化在数字化政务加速推进的今天&#xff0c;社保信息查询仍常依赖人工操作&#xff0c;效率低且易出错。Open-AutoGLM 作为一款融合大语言模型与自动化流程引擎的开源工具&#xff0c;为社保系统提供了端…

作者头像 李华
网站建设 2026/6/14 20:01:01

紧急通知:全国首批Open-AutoGLM试点单位名单公布,你的城市在列吗?

第一章&#xff1a;紧急通知&#xff1a;全国首批Open-AutoGLM试点单位名单公布&#xff0c;你的城市在列吗&#xff1f;国家人工智能发展办公室于今日正式发布《关于推进自主可控大模型应用落地的指导意见》&#xff0c;并同步公布了全国首批Open-AutoGLM试点单位名单。该计划…

作者头像 李华
网站建设 2026/6/15 12:49:07

为什么90%的洗车平台都失败了?Open-AutoGLM架构设计中的6个关键决策

第一章&#xff1a;为什么90%的洗车平台都失败了&#xff1f;在共享经济与O2O模式兴起的浪潮中&#xff0c;无数创业者涌入“互联网洗车”赛道&#xff0c;试图复制滴滴或美团的成功路径。然而现实残酷——超过90%的洗车平台在18个月内倒闭。其根本原因并非市场需求不足&#x…

作者头像 李华
网站建设 2026/6/14 15:08:43

Open-AutoGLM如何破解社保数据获取难题:技术架构与接口调用深度剖析

第一章&#xff1a;Open-AutoGLM社保查询自动化概述Open-AutoGLM 是一种基于大语言模型驱动的自动化工具框架&#xff0c;专为高频、重复性政务操作场景设计&#xff0c;其中社保查询自动化是其典型应用之一。该系统结合自然语言理解与浏览器自动化技术&#xff0c;能够模拟用户…

作者头像 李华
网站建设 2026/6/15 12:38:49

【Open-AutoGLM公积金提取全攻略】:手把手教你智能高效完成提取流程

第一章&#xff1a;Open-AutoGLM公积金提取全攻略概述Open-AutoGLM 是一款基于开源自动化框架与大语言模型协同工作的智能工具&#xff0c;专为简化复杂政务流程而设计。在公积金提取这一高频民生场景中&#xff0c;该系统通过语义理解、表单自动填充与多平台接口联动&#xff…

作者头像 李华
网站建设 2026/6/15 11:59:03

揭秘Open-AutoGLM油站数据接口:如何在5分钟内实现精准查询与调用

第一章&#xff1a;Open-AutoGLM 加油站点查询Open-AutoGLM 是一个面向智能交通场景的开源语言模型应用框架&#xff0c;支持自然语言驱动的实时数据查询与分析。在加油站点查询场景中&#xff0c;用户可通过自然语言指令快速获取周边加油站位置、油价、营业状态等关键信息。功…

作者头像 李华