题目
leetcode3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
代码
- 思路
- 类似动态规划的思路
- 假设以下标 i 结尾的最长无重复子串的长度为 maxlen(i), 则有 maxlen(0) = 1;
- i > 0时,分两种情况:在 s[i - maxlen(i)] ~ s[i -1] 子串中倒序查找 s[i]:
- 若未找到,即不重复,则有 maxlen(i) = maxlen(i - 1) + 1;
- 若找到, 假设重复元素下标位置为 j, 则有 maxlen(i) = i - j;此种情况maxlen(i) <= maxlen(i - 1);
- maxlen(i)(i < len(s))的最大值即为maxlen。
- 代码
// C
#include <string.h>
int lengthOfLongestSubstring(char* s) {
int len = strlen(s);
if (!len) {
return 0;
}
int cur_max_len = 1; // 以下标 i 结尾的最长无重复子串的长度
int max_len = 1; // 结果最大值
for (int i = 1; i < len; ++i){
// 在 s[i - cur_max_len] ~ s[i - 1] 子串中寻找 s[i]
int j = i - 1;
while(j >= i - cur_max_len && s[j] != s[i]){
--j;
}
if (j < (i - cur_max_len)) {
cur_max_len = cur_max_len + 1;
} else {
cur_max_len = i - j;
continue; // 此种情况不用计算max_len,因为此cur_max_len不会大于上一个cur_max_len
}
max_len = max_len > cur_max_len ? max_len : cur_max_len;
}
return max_len;
}
// C++
#include <string>
using namespace std;
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if (s.empty()) {
return 0;
}
int cur_max_len = 1;
int max_len = 1;
for (int i = 1; i < s.size(); ++i) {
auto idx = s.substr(i - cur_max_len, cur_max_len).find_last_of(s[i]);
if (idx == string::npos) {
cur_max_len = cur_max_len + 1;
} else {
cur_max_len = cur_max_len - idx;
continue;
}
max_len = max_len > cur_max_len ? max_len : cur_max_len;
}
return max_len;
}
};
测试
#include <iostream>
using namespace std;
int main(){
{
char* s = "pwwkew";
cout << s << " : " << lengthOfLongestSubstring(s) << endl;
}
{
string str = "pwwkew";
Solution s;
cout << str << " : " << s.lengthOfLongestSubstring(str) << endl;
}
cin.get();
return 0;
}
- 结果
pwwkew : 3
pwwkew : 3