Leetcode 003 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.
最终的Solution
int lengthOfLongestSubstring(string s) {
int mostRecentlyPosition[256], start = -1, maxLen = 0;
for (int i=0; i<256; i++) {
mostRecentlyPosition[i] = -1;
}
for (int i=0; i<s.length(); i++) {
if (mostRecentlyPosition[s[i]] > start) {
start = mostRecentlyPosition[s[i]];
}
mostRecentlyPosition[s[i]] = i;
maxLen = max(maxLen, i - start);
}
return maxLen;
}
分析
这个解法是比较好的,明显可以看到,只有一重循环,次数是s
的长度,时间复杂度达到了O(n)
。
这个解法的思想大致是这样的,mostRecentlyPosition
记录每个字符出现的最后位置,start
记录我们当前计算的子字符串的开始位置。
我们以"pwwkew"
为例:
- 我们将
mostRecentlyPosition
都置为-1,start
也置为-1 - 首先,遍历
p
,w
,可以记录mostRecentlyPosition['p'] = 0, mostRecentlyPosition['w'] = 1
; - 下面又到了
w
,此时我们发现mostRecentlyPosition['w'] = 1 > start
,这代表着w
字符在我们当前计算的子字符串中已经出现过了。因此我们将第一次出现的w
从我们的字符串中删去,也就是start
变成w
第一次出现位置的后一位,这样我们的子字符串中就没有重复的元素了。当然,此时我们要记录在遇到这个重复的w
之前一个时刻,我们计算到的字符串的最大长度; - 重复上述步骤
实际的使用中,由于我们初始start = -1
,我们不将start
标号的字符算在字符串中,因此我们没有+1。
之前还写过一些简单的方案
初始Solution
bool repeat[256];
string s;
int lengthOfLongestSubstring(string str)
{
s = str;
int len = s.length();
// O(n)
while (len != 0)
{
// O(n)
for (int i = 0; i + len <= s.length(); i++)
{
// O(n)
if (!hasRepeat(i, i + len))
{
return len;
}
}
len--;
}
return 0;
}
// O(n)
bool hasRepeat(int start, int end)
{
for (int i = 0; i < 256; i++) repeat[i] = false;
for (int i = start; i < end; ++i) {
if (repeat[s[i]]) return true;
repeat[s[i]] = true;
}
return false;
}
分析
这里就是巧妙地的暴力破解了,采用了一个浮动窗口,窗口的长度len
从string s
的长度,递减到0。每次都验证s
中连续的len
个字符是否重复,若重复则不符合;若不重复,那么就是最长的子串,直接return len
。
简单的分析该方法的时间复杂度,三重循环大致为
。
具体分析:
- 最外层
while(len != 0) {...}
为 ; - 次外层
for (int i = 0; i + len <= s.length(); i++) {...}
为 ; - 内层
hasRepeat(i, i + len)
为 ;
总体的复杂度为
嘿嘿其实我也不确定这个具体分析对不对,反正粗略来说肯定是 是没错了