leetcode:159.最多有两个不同字符的最长子串

题目来源

题目描述

给定一个字符串 s ,找出 至多 包含两个不同字符的最长子串 t ,并返回该子串的长度。

示例 1:

输入: “eceba”
输出: 3
解释: t 是 “ece”,长度为3。
示例 2:

输入: “ccaabbb”
输出: 5
解释: t 是 “aabbb”,长度为5。

class Solution {
public:
    int lengthOfLongestSubstringTwoDistinct(string s) {

    }
};

题目解析

思路

  • 用一个map,key为字符,value为字符出现次数。
  • 如果map的映射数量超过2个的时候,就删除一个映射
    • 比如此时 HashMap 中e有2个,c有1个,此时把b也存入了 HashMap,那么就有三对映射了
    • 这时 left 是0,先从e开始,映射值减1,此时e还有1个,不删除,left 自增1
    • 这时 HashMap 里还有三对映射,此时 left 是1,那么到c了,映射值减1,此时e映射为0,将e从 HashMap 中删除,left 自增1
  • 然后更新结果为 i - left + 1,以此类推直至遍历完整个字符串
class Solution {
public:
    int lengthOfLongestSubstringTwoDistinct(string s) {
        int res = 0, left = 0;
        unordered_map<char, int> m;
        for (int i = 0; i < s.size(); ++i) {
            ++m[s[i]];
            while (m.size() > 2) {
                if (--m[s[left]] == 0) m.erase(s[left]);
                ++left;
            }
            res = max(res, i - left + 1);
        }
        return res;
    }
};

思路

  • 用一个map,key为字符,value为字符最新的坐标
    • 比如题目中的例子 “eceba”,遇到第一个e,映射其坐标0,遇到c,映射其坐标1,遇到第二个e时,映射其坐标2,当遇到b时,映射其坐标3
  • 如果map的映射数量超过2个的时候,就删除一个映射
    • 从left开始往右找,看每个字符在map中的映射值是否等于当前left()
    • 比如第一个e,HashMap 此时映射值为2,不等于 left 的0,那么 left 自增1,遇到c的时候,HashMap 中c的映射值是1,和此时的 left 相同,那么我们把c删掉,left 自增1,再更新结果
class Solution {
public:
    int lengthOfLongestSubstringTwoDistinct(string s) {
        int res = 0, left = 0;
        unordered_map<char, int> m;
        for (int i = 0; i < s.size(); ++i) {
            m[s[i]] = i;
            while (m.size() > 2) {
                if (m[s[left]] == left) m.erase(s[left]);
                ++left;
            }
            res = max(res, i - left + 1);
        }
        return res;
    }
};

类似题目

题目思路
leetcode:643. 长度为k的子数组的最大平均数 maximum-average-subarray-i维护一个长度为k的滑动窗口,找到其中最大的那个sum,最后sum/k
leetcode:904. 最长子串:最多有两个不同字符 Fruit Into Baskets滑动窗口
leetcode:159. 最长子串:最多有两个不同字符 Longest Substring with At Most Two Distinct Characters 滑动窗口
leetcode:340. 最长子串:最多有K个不同字符Longest Substring with At Most K Distinct Characters滑动窗口
leetcode:3. 最长子串:无重复字符的最长子串 Longest Substring Without Repeating Characters
leetcode:76. 最小子串:字符串s2覆盖s1的所有子串的最小子串 Minimum Window Substring滑动窗口 + 欠账表
leetcode:424. 最小子串长度:替换后的最长相同字符的子串 longest-repeating-character-replacement
leetcode:395. 最长子串长度:每个字符至少重复K次的最长子串 Longest Substring with At Least K Repeating Characters整个字符串中,必须只包含1种元素,而且每种元素个数必须>=k时,其最长子串长度;整个字符串中,必须只包含2种元素,而且每种元素个数必须>=k时,其最长子串长度…
leetcode:992. 子数组个数:刚好包含K 个不同整数的子数组 subarrays-with-k-different-integers
leetcode:209. 最小子数组长度:无序正数数组其和>=k的长度最小的子数组的长度 Minimum Size Subarray Sum 滑动窗口
leetcode:239. 滑动窗口最大值Sliding Window Maximum

| 1052. 爱生气的书店老板
| 1156. 单字符重复子串的最大长度
| 1343. 大小为 K 且平均值大于等于阈值的子数组数目
| 1456. 定长子串中元音的最大数目
| 2348. 全 0 子数组的数目
| 1004 最大连续1的个数 III
| 713. 乘积小于 K 的子数组;
| 795. 区间子数组个数;
| 1358. 包含所有三种字符的子字符串数目;
| 467. 环绕字符串中唯一的子字符串;
| 2024.考试的最大困惑
| 1208. 尽可能使字符串相等

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值