003 Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for “abcabcbb” is “abc”, which the length is 3. For “bbbbb” the longest substring is “b”, with the length of 1.
Input: abcabccbb
Output: 3
题意:找到一个字符串中,没有重复字符的最长子串,返回它的长度
思路:
- 做一个一维数组HashTable,下标为字符的ASCII码,值为这个字符在字符串中的位置,初始化为-1
- 设置一个变量LastPosition表示不重复最长串的第一个元素的下标
- 遍历字符串,依次检测该字符是否存在HashTable中,例:
HashTable['a']=-1
表示该字符第一次出现。
HashTable['a']=2
表示该字符上一次出现的位置在str[2]. - 如果第一次出现该字符a,HashTable[‘a’]=字符’a’在字符串中的位置.
- 如果已经出现过字符’a’,如果上一次’a’在目前检测串中,则置LastPosition为a的下标(即上一次LastPostion)。否则置LastPosition为当前检测字符的下标(HashTable[temp])。
该下标一定为:LastPosition=std::max(LastPosition,HashTable[temp]);
- Max为
HashTable[temp]-LastPostion
所能得到的最大值
a | b | c | d | a |
---|
0 | 1 | 2 | 3 | 5 |
---|
代码:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int Max=0;
int LastPosition=0;
int HashTable[255]={-1};
int i=0;
for(i=0;i<s.size();i++){
int temp=(int)s[i];
if(HashTable[temp]>0){
LastPosition=std::max(LastPosition,HashTable[temp]);
}
HashTable[temp]=i+1;
Max=std::max(Max,HashTable[temp]-LastPosition);
}
return Max;
}
};
知识点
- 字符串中寻找最长符合要求的子串
- 难点:当检测到重复字符时,应该从何处继续检测
- 还有一种DP解法如下,其实上面的代码也是DP,DP指通过状态转移来解决问题的一种思路,每一种状态的决定总是与上一次状态有联系,以下代码中,Flag数组就是一种记录状态,而Longest每次依赖于上一次Longest还有Flag数组中的状态,因此说这种解决思路是一种DP思路。这个代码由LeetCode上的prime_tang所写,此处为引用。我询问后,他对DP思路的描述原文如下:
In my understanding, the dynamic programming is: every decision depends on the current status, and immediately cause the transfer of status. In this problem, flag is the status, and we can get the longest every time depends on the previous longest and the flag, so I think it also can be seen as DP solution, even though not obvious compared to the Maximum Subarray problem.
class Solution {
public:
int lengthOfLongestSubstring(std::string s) {
std::vector<int> flag(256, -1);
int start = 0, longest = 0, len = s.size();
for (int i = 0; i != len; ++i) {
if (flag[s[i]] >= start) {
longest = std::max(longest, i - start);
start = flag[s[i]] + 1;
}
flag[s[i]] = i;
}
return std::max(longest, len - start);
}
};