题目描述:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例:
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是"abc",所以其
长度为 3。
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是"b"
,所以其长度为 1。
思路分析:
这道题是median难度,一开始看到这种求最大最小的题最先想到的是用动态规划,后来看了网上的相关题解才知道用到的是哈希表和滑动窗口的思想。
由于求的连续子串,所以可以考虑用一个滑动窗口来限定这个子串的范围,那么我们的目标是希望这个窗口当中无重复的字符,且使得窗口尽量的大。可以用一个left指针来维持这个窗口的左边界,当前遍历到的字符位置为窗口的右边界。利用哈希表来存储每个字符最后出现的位置,由于字符的ascii码范围,所以可以直接设定一个256长度的数组来存。子串的长度通过i-left+1来表示,在每次遍历时,首先去判断这个字符是否出现过和当前的left指针是否大于这个字符之前出现的位置(这么做的目的看这个字符是否在当前的滑动窗口中),若未出现或小于left,则更新最长子串的长度。在每次遍历的最后,需要更新当前字符最后出现的位置。
下面有一个博客的解析写得比较清晰,可以参考:https://www.cnblogs.com/ariel-dreamland/p/8668286.html
另外,在自己重现的过程中,遇到的一个问题是,数组的初始化,发现利用int a[256]={0}来初始化所有的元素为0是可以的,但其他数就无法赋值所有元素,而只能是第一个元素。这是c++的初始化过程中我们很容易有的一个误区,具体可以参考这里:https://blog.csdn.net/u014417133/article/details/77185009/
代码:
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s) { 4 vector<int> m(256, -1); 5 int res=0, left=0; 6 for(int i=0; i<s.size(); i++) 7 { 8 if(m[s[i]]==-1 || m[s[i]]<left) 9 { 10 res = max(res, i-left+1); 11 } 12 else 13 { 14 left = m[s[i]]+1; 15 } 16 m[s[i]] = i; 17 } 18 return res; 19 } 20 };