解法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; } };