LeetCode 3 Longest Substring Without Repeating Characters
题目大意是给一个字符串,需要求出最大的子串(子串中没有任何元素是相同的)
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequence and not a substring.
最初想的比较简单,O(n^2)
class Solution { public: map<char,int>mp; int lengthOfLongestSubstring(string s) { int len=s.length(); if(len==1) { return 1; } int temp=0,max=0,i,j; for(i=0;i<len;i++) { mp[s[i]]=1; for(j=i+1;j<len;j++) { if(mp[s[j]]==0) mp[s[j]]=1; else { break; } } temp=j-i; mp.clear(); if(temp>max) { max=temp; } } return max; } };
其实这个题目有点类似于双指针了。两个指针 i , j表示从i开始到j都是没有相同单元的。这里我们可以用一个set容器来维护。如果到了某一个j,发现出现相同的元素,则将i向前移,同时删除set中对应i节点的内容
class Solution { public: set<char>p; int lengthOfLongestSubstring(string s) { int len=s.length(); int i=0,j=0,ans=0; while(i<len&&j<len) { if(p.count(s[j])==0) { p.insert(s[j++]); ans=max(ans,j-i); } else { p.erase(s[i++]); } } return ans; } };
我们发现其实还可以继续降低复杂度,因为当我们发现s[j] 已经出现在前面时,我们是从i一个个寻找的。而我们可以用一个map记录与s[j]相等的j'的位置
class Solution { public: map<char,int>mp; int lengthOfLongestSubstring(string s) { int len=s.length(); int i=0,j=0,ans=0; for(j=0,i=0;i<len&&j<len;j++) { if(mp.count(s[j])!=0) { i=max(i,mp[s[j]]); } ans=max(ans,j-i+1); mp[s[j]]=j+1; //yao从下一个不相同的元素开始,所以+1 } return ans; } };