问题描述:
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
从下标0开始,依次查找以当前下标开始的最长不重复子序列。
举例说明:
C++代码实现:
int GetMaxLength(string& sTemp, int startIndex) { map<char, int> mapChar; int max = 0; for (int i = startIndex; i < sTemp.length(); ++i) { if (mapChar.find(sTemp[i]) != mapChar.end()) return max; mapChar[sTemp[i]] = i; ++max; } return max; } int lengthOfLongestSubstring(string s) { int max = 0; for (int i = 0; i < s.length(); ++i) { int temp = GetMaxLength(s, i); if (temp > max) max = temp; } return max; }
思路2
设当前检测的子序列,下标最小值为m,最大值为n(即子串strInput[m,n]),则当前检测序列的长度为n-m+1。
如果该序列中没有重复元素,那么它的长度可以作为最长无重复子序列长度的一个候选值(如果后来有的序列长度超过了它,就替换掉)
我们设当前检测序列的起始下标为now,遍历整个字符串,遍历中当前下标为i;如果可以保证从now到i中没有重复元素,遍历一次,就可以利用i-now+1找到最长无重复子序列。
使now从0开始,后移遍历下标i,直到strInput[now,i]中出现重复的字符,更新now的值,将now移动到重复字符第一次出现的下标后即可。
举例说明:
可以将字符和下标存入哈希表中,这样在查找新加入的字符是否在原始检索串中存在时,时间复杂度为1。
C++代码实现:
int lengthOfLongestSubstring(string s) { int maxLength = 0; int now = 0; map<char, int> charMap; for (int i = 0; i < s.length(); ++i) { if (charMap.find(s[i]) != charMap.end()) { now = charMap[s[i]] + 1 > now ? charMap[s[i]] + 1 : now; } if (i - now + 1>maxLength) { maxLength = i - now + 1; } charMap[s[i]] = i; } return maxLength; }
思路2优化
由于在C++中字符和数字转换非常简单,所以,可以用一个数组来替代哈希表:
C++代码实现:
int lengthOfLongestSubstring(string s) { int maxLength = 0; int now = 0; int charMap[256]; for (int i = 0; i < 256; ++i) { charMap[i] = -1; } const char *p = s.c_str(); for (int i = 0; i < s.length(); ++i) { if (charMap[p[i]] != -1) { now = charMap[p[i]] + 1 > now ? charMap[p[i]] + 1 : now; } if (i - now + 1>maxLength) { maxLength = i - now + 1; } charMap[p[i]] = i; } return maxLength; }