LeetCode 热题 3.无重复字符的最长子串
题目
解法:
1. 暴力解法:
枚举所有子串,检查每个子串是否有重复字符。
int n = s.size();int res = 0;for (int i = 0; i < n; i ++) {unordered_set<char> m; // 记录这以 i 为起点的子串有什么字母for (int j = i; j < n; j ++) {if (m.count(s[j])) break; // 如果之前有这个字母了,就结束掉m.insert(s[j]); // 没有的话就加进去res = max(res, j - i + 1); // 重新计算一下长度}}return res;
2. 滑动窗口 经典解法:
思路:
求最长无重复字符的子串其实就是 求最长区间 [i, j] ,使得区间里没有任何字符的个数 > 1。
我们可以维护一个区间,让右指针一直往右走,直到区间里有字母的个数 > 1那就让左指针开始往前走,直到区间里字母的个数都 < 1.
这个写法因为 i 只增不减,j 只增不减,两个指针各走一边 所以是 O(n)的
代码如下:
int len = s.size();int res = 0;unordered_map<char, int> m; // 计数器,记录窗口里各个字母的个数// 这里注意 i 此时右边界, j 是左边界, i 一直在往前,j 只有在有重复字符的时候才往前for (int i = 0, j = 0; i < len; i ++ ){m[s[i]] ++; // 把新字符进窗口while (m[s[i]] > 1) { // 字符重复m[s[j]] --; // 把左侧的字符踢出去j ++; // j 往前挪}res = max(res, i - j + 1); // 直到区间里的字符都不重复,更新一下答案}return res;