3. Longest Substring Without Repeating Characters
Given a string, find the length of the 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.
解法1:遍历字符串找最长不重复字串,用hash表记录下已有的字符,用begin来记录开始计数的位置。如果下一个字符在hash表中已经记录了,就修改begin和hash的值来继续下一次查找
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s) { 4 int maxLength=0;//记录下最长的不重复字串的长度 5 int length=0; 6 int begin=0;//记录下开始计算长度的位置 7 short hash[128];//哈希表,ASCII码,最多不超过128个字符 8 memset(hash, 0, sizeof(hash)); 9 for(int idx=0; idx<s.size(); ++idx) 10 { 11 12 int key=s[idx]-'\0'; 13 if(hash[key]==0) 14 { 15 hash[key]=1; 16 ++length; 17 }else{ 18 if(length>maxLength)maxLength=length; 19 if(maxLength==128)return 128;//如果最大长度达到128,立即返回,无须再比较下去 20 while(s[begin]!=s[idx]) 21 { 22 int key=s[begin]-'\0'; 23 hash[key]=0; 24 --length; 25 ++begin; 26 } 27 ++begin; 28 } 29 } 30 if(length>maxLength)maxLength=length;//别忘了最后一次更新 31 return maxLength; 32 } 33 };
解法2:动态规划,遍历字符串,在hash表中存储的是字符在字符串中的位置,时间复杂度为O(n),比上面的算法更快
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s) { 4 int maxLength=0; 5 int length=0; 6 int hash[128]; 7 for(int i=0; i<sizeof(hash)/4; ++i)hash[i]=-1;//初始化为-1 8 for(int idx=0; idx<s.size(); ++idx) 9 { 10 int val=hash[s[idx]-'\0']; 11 if(val==-1 || idx-length>val)//如果为-1,表示没有出现,故length加1。如果出现在计数范围之前,不影响,同没有出现 12 ++length; 13 else{//如果出现在计数范围之内,更新maxLength,重置length 14 if(length>maxLength)maxLength=length; 15 if(maxLength==128)return 128; 16 length=idx-val; 17 } 18 hash[s[idx]-'\0']=idx; 19 } 20 if(length>maxLength)maxLength=length;//最后一次更新maxLength 21 return maxLength; 22 } 23 };