Description
Given a string, find the length of the longest substring without repeating characters.
给你一个字符串,求出其最长不重复字串的长度。
Example
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Solution 1: Brute Force(暴力)
#include <iostream>
#include <string>
#include <set>
using namespace std;
int lengthOfLongestSubstring(string s)
{
int len = s.length(); // 字符串长度
set<char> st;
int flag = 0;
for (int i = 0; i < len; i++)
st.insert(s[i]);
int size = st.size(); // 字符串中不同元素个数
st.clear();
for (int i = size; i >= 0; i--)
{
for (int k = 0; k <= len - i; k++)
{
for (int j = k; j < k + i; j++)
st.insert(s[j]);
if (st.size() == i)
{
flag = i;
break;
}
st.clear();
}
if (flag) // 跳出外层 for
break;
}
if (flag)
return flag;
}
int main(void)
{
string a = "fsfsd";
cout << lengthOfLongestSubstring(a) << '\n';
return 0;
}
结果…
这个测试案例。。,好吧,我承认,没想到。。。于是改进:
在最后 if 加了句
else
return 1;
然鹅。。。。。
这也太骚了吧!好吧,还是我菜,没想到空串。。
应该首先判断一下 size 的!
#include <iostream>
#include <string>
#include <set>
using namespace std;
int lengthOfLongestSubstring(string s)
{
int len = s.length();
set<char> st;
int flag = 0;
for (int i = 0; i < len; i++)
st.insert(s[i]);
int size = st.size();
st.clear();
if (size > 0)
{
for (int i = size; i >= 0; i--)
{
for (int k = 0; k <= len - i; k++)
{
for (int j = k; j < k + i; j++)
st.insert(s[j]);
if (st.size() == i)
{
flag = i;
break;
}
st.clear();
}
if (flag)
break;
}
if (flag)
return flag;
else
return 1;
}
else
return 0;
}
int main(void)
{
string a = " ";
cout << lengthOfLongestSubstring(a) << '\n';
return 0;
}
终于 AC 了,但是这个 Runtime 和 Memory 感动哭了(毕竟
O
(
n
3
)
O(n^3)
O(n3) )???
然后,去扒扒 Solution 里的高级解法去?
Solution 2
int lengthOfLongestSubstring(string s)
{
vector<int> dict(256, -1);
int maxLen = 0, start = -1;
for (int i = 0; i != s.length(); i++)
{
if (dict[s[i]] > start)
start = dict[s[i]];
dict[s[i]] = i;
maxLen = max(maxLen, i - start);
}
return maxLen;
}
说实话,hard to undertand!下面举例一步一步分析(以 “dfdfss” 为例):
程序从地一个字符开始遍历,如果这个字符之前出现过(dict[s[i]] > start
),则将该字符上一次出现的位置(dict[s[i]]
)赋给start
;如果这个字符之前未出现过,则start
值不变;然后将字符位置(i
)赋给 dict[s[i]]
,并计算 maxLen
。循环往复,理论上复杂度为
O
(
n
)
O(n)
O(n)。
观察下表可以看出,i-start
始终表示从该字符往前所能表示的最大不重复字串的长度。
i | △s | s[ i ] | start | dict[ s[ i ] ] | i - start | maxLen |
---|---|---|---|---|---|---|
0 | d | d | -1 | -1?0 | 1 | 0?1 |
1 | df | f | -1 | -1?1 | 2 | 1?2 |
2 | dfd | d | -1?0 | 0?2 | 2 | 2 |
3 | dfdf | f | 0?1 | 1?3 | 2 | 2 |
4 | dfdfs | s | 1 | -1?4 | 3 | 2?3 |
5 | dfdfss | s | 4 | 4?5 | 1 | 3 |