leetcode:3. 无重复字符的最长子串
3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
法1:通过暴力破解,遍历一次字符串,每次将新加的字符和字符串比较,有重复,就刷新字符串的左边界,没重复,就继续加。
class Solution { public: int lengthOfLongestSubstring(string s) { int left=0,right=1,len=1,res=0; int s_len=s.length(); if(s_len<2)return s_len; //防止空串和只有一个字符的情况 while(right<s_len){ //遍历整个字符串 for(int i=left;i<right;i++){ //遍历新添加的字符在前边字符串中是否重复 if(s[i]==s[right]){ left=i+1; len=right-left; break; } } right++; len++; res=max(len,res); } return res; } };
法2:使用map来大大降低字符查重的时间
class Solution { public: int lengthOfLongestSubstring(string s) { int left=0,right=0,len=0,res=0; unordered_map<char,int>hash; int s_len=s.length(); while(right<s_len){ //遍历整个字符串 if(hash.find(s[right])!=hash.end()&&hash[s[right]]>=left){ //若重复 left=hash[s[right]]+1; //更新左边界 len=right-left; //更新长度 } hash[s[right]]=right; //加入到map里 right++; len++; res=max(len,res); } return res; } };
法3:利用vector数组来代替map,桶排序的思想。
class Solution { public: int lengthOfLongestSubstring(string s) { int left=0,right=0,len=0,res=0; vector<int>v(128,-1); int s_len=s.length(); while(right<s_len){ //遍历整个字符串 char tempChar=s[right]; if(v[(int)tempChar]>=left){ //如果字符tempChar没出现过,那v[tempChar]值就是 //-1,出现过的话,v[tempChar]就是上次出现的下标了 left=v[tempChar]+1; len=right-left; } v[tempChar]=right; //更新v[tempChar] right++; len++; res=max(len,res); } return res; } };