解题思路
这是一个经典的滑动窗口问题,需要:
-
滑动窗口策略:
- 使用两个指针( 和 )维护一个窗口
- 右指针不断向右扩展,直到遇到重复字符
- 左指针向右移动,直到删除重复字符
-
字符记录:
- 使用数组或哈希表记录每个字符最后出现的位置
- 当遇到重复字符时,更新左指针位置
-
最大长度更新:
- 在窗口移动过程中,持续更新最大长度
- 最大长度 = max(当前最大长度, )
代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> last(128, -1); // 记录字符最后出现的位置
int maxLen = 0;
int left = 0;
for (int right = 0; right < s.length(); right++) {
// 如果字符已经在窗口中出现过,更新左边界
if (last[s[right]] >= left) {
left = last[s[right]] + 1;
}
// 更新字符最后出现的位置
last[s[right]] = right;
// 更新最大长度
maxLen = max(maxLen, right - left + 1);
}
return maxLen;
}
};
int main() {
string s;
cin >> s;
Solution solution;
cout << solution.lengthOfLongestSubstring(s) << endl;
return 0;
}
import java.util.*;
public class Main {
static class Solution {
public int lengthOfLongestSubstring(String s) {
int[] last = new int[128]; // 记录字符最后出现的位置
Arrays.fill(last, -1);
int maxLen = 0;
int left = 0;
for (int right = 0; right < s.length(); right++) {
char c = s.charAt(right);
if (last[c] >= left) {
left = last[c] + 1;
}
last[c] = right;
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
Solution solution = new Solution();
System.out.println(solution.lengthOfLongestSubstring(s));
}
}
def length_of_longest_substring(s: str) -> int:
last = {} # 记录字符最后出现的位置
max_len = left = 0
for right, char in enumerate(s):
# 如果字符已经在窗口中出现过,更新左边界
if char in last and last[char] >= left:
left = last[char] + 1
# 更新字符最后出现的位置
last[char] = right
# 更新最大长度
max_len = max(max_len, right - left + 1)
return max_len
if __name__ == "__main__":
s = input().strip()
print(length_of_longest_substring(s))
算法及复杂度
- 算法:滑动窗口
- 时间复杂度:,其中 是字符串长度
- 空间复杂度:,因为字符集大小是固定的