解题思路

这是一个经典的滑动窗口问题,需要:

  1. 滑动窗口策略

    • 使用两个指针()维护一个窗口
    • 右指针不断向右扩展,直到遇到重复字符
    • 左指针向右移动,直到删除重复字符
  2. 字符记录

    • 使用数组或哈希表记录每个字符最后出现的位置
    • 当遇到重复字符时,更新左指针位置
  3. 最大长度更新

    • 在窗口移动过程中,持续更新最大长度
    • 最大长度 = 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))

算法及复杂度

  • 算法:滑动窗口
  • 时间复杂度:,其中 是字符串长度
  • 空间复杂度:,因为字符集大小是固定的