其他分享
首页 > 其他分享> > leetcode小白刷题之旅----3. Longest Substring Without Repeating Characters

leetcode小白刷题之旅----3. Longest Substring Without Repeating Characters

作者:互联网

仅供自己学习,有借鉴成分。

 

题目:

Given a string s, find the length of the longest substring without repeating characters.

 

思路:

1.下意识想到暴力是可以求解的,把所有无重复字母子串记录下来再来比较。但从每个字母开始遍历则总RT为O(n^2)

2.除了暴力后,自己在想的方法都很麻烦,而且和暴力求解差别不大。看了题解了解到一个滑动窗口的算法。简单来说就是用两个tag,一个记录子串最左元素位置,另一个记录子串最右元素位置。主要判断即查看子串中是否有相同元素,无则右tag拓展,否则将左tag移动到该子串中相同的元素后。了解到这个算法后思路就比较清晰了,下面是一些细节和技巧的处理。

(1).使用哈希表以S里的每个元素为key值,其下标为value,可以以O(1)的速度判断是否有重复的元素。

(2).更为简便的方法。将循环递增的 i 视为右tag,若要获得子串长度只需要 i-left ,这也就将left设在子串最左元素的前一个元素位置。

(3).此种方法会导致一个特殊情况,就是left tag因为重复元素移动后可能导致现在的子串长度比上一个子串长度更短,故子串长度 maxlen应该取 (maxlen,i-left)的最大值

(4).哈希表能迅速判断该元素是否被映射过,但如何判断在子串当中呢。即在该判断条件下增加 m[s[i]] > left即可,因为value是该元素在字符串的位置,故可判断是否在子串内。

综上,算法只遍历一遍字符串,故RT为O(n)

 

代码

这里第6行的for循环,并不需要先遍历所有字符串元素一一映射后在进行操作。这样先判断后映射并不会影响最终结果,并且当遇到第一个重复元素前,maxlen都在增,left不变,每个映射都被记录。直到left移动后,之前映射的关系都足够之后的判断,否则不会进入if,继续映射下去

 1 class Solution {
 2 public:
 3     int lengthOfLongestSubstring(string s) {
 4         unordered_map <char,int> m;
 5         int maxlen=0,left=-1;
 6         for(int i=0;i<s.size();i++)
 7         {
 8             if(m.count(s[i]) && m[s[i]] > left )
 9                 left = m[s[i]];
10             m[s[i]] = i;
11             maxlen = max(maxlen,i-left);
12         }
13         return maxlen;
14     }
15 };

标签:子串,----,映射,小白刷题,元素,Substring,maxlen,tag,left
来源: https://www.cnblogs.com/Mrsdwang/p/14319451.html