Given a string S, find the length of the longest substring T that contains at most two distinct characters.
For example,
Given S = “eceba”,
T is “ece” which its length is 3.

这道题给我们一个字符串,让我们求最多有两个不同字符的最长子串。那么我们首先想到的是用哈希表来做,哈希表记录每个字符的出现次数,然后如果哈希表中的映射数量超过两个的时候,我们需要删掉一个映射,比如此时哈希表中e有2个,c有1个,此时把b也存入了哈希表,那么就有三对映射了,这时我们的left是0,先从e开始,映射值减1,此时e还有1个,不删除,left自增1。这是哈希表里还有三对映射,此时left是1,那么到c了,映射值减1,此时e映射为0,将e从哈希表中删除,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;}
};

我们除了用哈希表来映射字符出现的个数,我们还可以映射每个字符最新的坐标,比如题目中的例子"eceba",遇到第一个e,映射其坐标0,遇到c,映射其坐标1,遇到第二个e时,映射其坐标2,当遇到b时,映射其坐标3,每次我们都判断当前哈希表中的映射数,如果大于2的时候,那么我们需要删掉一个映射,我们还是从left=0时开始向右找,我们看每个字符在哈希表中的映射值是否等于当前坐标left,比如第一个e,哈希表此时映射值为2,不等于left的0,那么left自增1,遇到c的时候,哈希表中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;}
};

后来又在网上看到了一种解法,这种解法是维护一个sliding window,指针left指向起始位置,right指向window的最后一个位置,用于定位left的下一个跳转位置,思路如下:

1. 若当前字符和前一个字符相同,继续循环。

2. 若不同,看当前字符和right指的字符是否相同

(1) 若相同,left不变,右边跳到i - 1

(2) 若不同,更新结果,left变为right+1,right变为i - 1

最后需要注意在循环结束后,我们还要比较res和s.size() - left的大小,返回大的,这是由于如果字符串是"ecebaaa",那么当left=3时,i=5,6的时候,都是继续循环,当i加到7时,跳出了循环,而此时正确答案应为"baaa"这4个字符,而我们的res只更新到了"ece"这3个字符,所以我们最后要判断s.size() - left和res的大小。

另外需要说明的是这种解法仅适用于于不同字符数为2个的情况,如果为k个的话,还是需要用上面两种解法。

解法三:

class Solution {
public:int lengthOfLongestSubstringTwoDistinct(string s) {int left = 0, right = -1, res = 0;for (int i = 1; i < s.size(); ++i) {if (s[i] == s[i - 1]) continue;if (right >= 0 && s[right] != s[i]) {res = max(res, i - left);left = right + 1;}right = i - 1;}return max(s.size() - left, res);}
};

本文转自博客园Grandyang的博客,原文链接:最多有两个不同字符的最长子串[LeetCode] Longest Substring with At Most Two Distinct Characters ,如需转载请自行联系原博主。

[LeetCode] Longest Substring with At Most Two Distinct Characters 最多有两个不同字符的最长子串...相关推荐

  1. [LeetCode] 159. Longest Substring with At Most Two Distinct Characters 最多有两个不同字符的最长子串...

    Given a string S, find the length of the longest substring T that contains at most two distinct char ...

  2. [LeetCode] Longest Substring with At Most K Distinct Characters 最多有K个不同字符的最长子串...

    Given a string, find the length of the longest substring T that contains at most k distinct characte ...

  3. 386 · Longest Substring with At Most K Distinct Characters最多有k个不同字符的最长子字符串

    链接:https://www.lintcode.com/problem/386/description https://mp.weixin.qq.com/s?__biz=MzU2OTUyNzk1NQ= ...

  4. leetcode Longest Substring with At Most Two Distinct Characters 滑动窗口法

    题目解析 代码如下 题目解析 这一题是一道会员的题目,题目介绍如下: Given a string, find the length of the longest substring T that c ...

  5. LeetCode 159. Longest Substring with At Most Two Distinct Characters --Java,C++,Python解法

    题目地址:Longest Substring with At Most Two Distinct Characters - LeetCode Given a string s , find the l ...

  6. LeetCode 340. Longest Substring with At Most K Distinct Characters

    原题链接在这里:https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/ 题目: Give ...

  7. LeetCode 159. 至多包含两个不同字符的最长子串(滑动窗口)

    文章目录 1. 题目 2. 解题 1. 题目 给定一个字符串 s ,找出 至多 包含两个不同字符的最长子串 t ,并返回该子串的长度. 示例 1: 输入: "eceba" 输出: ...

  8. 力扣(LeetCode)159. 至多包含两个不同字符的最长子串(2022.06.08)

    给定一个字符串 s ,找出 至多 包含两个不同字符的最长子串 t ,并返回该子串的长度. 示例 1: 输入: "eceba" 输出: 3 解释: t 是 "ece&quo ...

  9. Longest Substring With At Most K Distinct Characters

    Given a string, find the length of the longest substring T that contains at most k distinct characte ...

最新文章

  1. Weex快速上手教程(Weex Tutorial)
  2. 将jar文件转换成exe可执行文件
  3. java 调用SAP RFC函数错误信息集锦
  4. nginx alias php 404,Nginx配置静态服务器以及404问题解决,root和alias的区别
  5. 每日一题(30)—— 局部变量能否和全局变量重名?
  6. 【计算机网络】核心知识归纳总结
  7. 几行代码轻松实现瀑布流显示。
  8. php ajax jquery 表单重复提交,jQuery如何防止Ajax重复提交
  9. SPA (单页应用程序)
  10. mysql 当前时区_如何获取MySQL的当前时区?
  11. 心理软件测试自学,软件测试中的心理学
  12. 北美前景最好25种职业 软件工程师独占鳌头
  13. RPN Calculator for mac(RPN计算器)
  14. 世界中英文国家及国家代码
  15. thinkphp自定义汉字转拼音类
  16. 【20211208】【Python】UCI数据集的简单介绍和使用Python保存UCI数据集为.mat文件
  17. 全国各省份简称、省会、经纬度
  18. 阿里云——弹性公网IP
  19. [ACM]【Dijkstra/DP】Atcoder 164 Two Currencies
  20. 阿里云ECS学习资源

热门文章

  1. excel 区间人数柱状图_原来用Excel做数据分析如此简单!
  2. java frame linux_JAVA环境(下) - Android框架简介_Linux编程_Linux公社-Linux系统门户网站...
  3. img之间出现缝隙的原因_神马情况?美缝剂施工出现脱胶是什么原因?
  4. ASP.NET的ADO(ActiveX Data Objects)
  5. php 实现一致性哈希,PHP一致性哈希实现。。
  6. 整数反转Java_详解 LeetCode_007_整数反转(Java 实现)
  7. 浅谈智能卡加密芯片在智能设备领域的技术运用
  8. 遇劣势变蠢、发语音嘲讽人类……OpenAI这些奇葩DOTA操作跟谁学的?
  9. Facebook要造芯片了,开发团队正在组建中
  10. 这么多人,AI怎么知道你说的是哪个? | 李飞飞团队CVPR论文+代码