解法1:暴力法ios
解題步驟:數組
①找出字符串中的全部子串:兩層循環實現spa
②判斷子串中是否有重複字符:set實現code
遍歷子串,若是set中有該字符,則返回false,不然返回trueblog
#include<iostream> #include<set> #include<string> using namespace std; class Solution{ public: int lengthOfLongestSubstring(string s){ int n = s.length(); int count=0; for(int i=0;i<n;++i){ for(int j=i+1;j<=n;++j){ if(allUnique(s,i,j)){ if(count<j-i) count = j-i; } } } return count; } bool allUnique(string s, int start, int end){ set<char> set; for(int i=start; i<end; ++i){ if(set.count(s[i]) != 0){ return false; } set.insert(s[i]); } return true; } }; int main(){ Solution solution; string s; cin>>s; int num; num = solution.lengthOfLongestSubstring(s); cout<<num<<endl; return 0; }
解法2:滑動窗口法ci
在本題中窗口表示不含重複字符的子串,用res表示最大不重複子串的長度。字符串
爲了計算滑動窗口的長度,咱們用left表示窗口的左邊界,窗口的右邊界就是當前遍歷到的字符。string
如何判斷字符重複出現?咱們須要記錄字符和它出現位置的映射。咱們用一個256位大小的數組來代替哈希表表示字符最後出現的位置。該數組初始化全爲0,表示全部字符都還沒出現過。而後不斷滑動窗口右邊界,觀察右邊界對應的字符是否出現過,也即判斷left是否須要更新。若數組中該字符對應的位置爲0,則表示該字符從未出現過,left不變。若數組中該字符對應的位置不爲0,說明該字符以前出現過,可是這個重複字符有可能在滑動窗口內部也有可能在滑動窗口左邊。則接下來判斷該字符是否在滑動窗口內部,若該字符的位置大於left,則表示該字符在滑動窗口內部,則移動left至重複字符處。若該字符的位置小於left,則表示該字符不在滑動窗口內部,無需更新left。io
滑動窗口每次向右滑動一個字符,對應的數組中字符位置更新爲i+1,而後比較res和滑動窗口的大小決定是否更新res。class
class Solution{ public: int lengthOfLongestSubstring(string s){ int m[256] = {0}, res = 0, left = 0; for(int i=0;i<s.size();++i){ // if(m[s[i]] == 0 || m[s[i]] < left){ // res = max(res, i-left+1); // } // else{ // left = m[s[i]]; // } // m[s[i]] = i+1; ////精簡寫法 left = max(left, m[s[i]]); m[s[i]] = i+1; res = max(res, i-left+1); } return res; } };
解法2.2: 滑動窗口法
使用了HashMap創建字符和其最後出現位置之間的映射,其餘操做同上
class Solution{ public: int lengthOfLongestSubstring(string s){ int res=0, left=0; unordered_map<char, int> m; for(int i=0;i<s.size();++i){ left = max(left, m[s[i]]); m[s[i]] = i+1; res = max(res, i-left+1); } return res; } };