『1』双指针算法
我的想法:
一般看到字符串子串问题想到用双指针解,看到字符串子序列问题想到用动态规划解。此题用双指针可以很快解题。
- 遍历字符串中的每个字符
s.charAt[i]
, 对于每一个i
,找到j
使得双指针[j, i]维护的是以s.charAt[i]
结尾的无重复字符的最长子串,长度为i - j + 1
, 将这一长度与res
的较大者更新给res
。
- 对于每一个
i
,如何确定j
的位置:由于[j, i - 1]是前一步得到的无重复字符的最长子串,所以如果[j, i]中有重复元素,一定是s.charAt[i]
,因此右移j
直到s.charAt[i]
不重复为止(由于[j, i - 1]已经是前一步的最优解,此时j
只可能右移以剔除重复字符s.charAt[i]
,不可能左移增加字符,因此,j
具有单调性、本题可用双指针算法降低复杂度)。 - 用数组hash记录字符
s.charAt[i]
在当前窗口中出现的次数,遍历过程中对于每一个i
有四步操作:获取字符s.charAt[i]
-> 将s.charAt[i]
出现次数hash[s.charAt[i]]
加1 -> 若s.charAt[i]
重复则右移j
(先把s.charAt[j]次数减1,再右移j) -> 确定j
及更新当前长度i - j + 1
给res
。
实现代码:
class Solution {
// Sliding Window
// N is the length of s
// Time Complexity: O(N)
// Space Complexity: O(1)
public int lengthOfLongestSubstring(String s) {
if (s.length() <= 1) return s.length();
int res = 0;
int[] hash = new int[127];
for (int i = 0, j = 0; i < s.length(); i++) {
hash[s.charAt(i)]++;
while (hash[s.charAt(i)] > 1) --hash[s.charAt(j++)];
res = Math.max(res, i - j + 1);
}
return res;
}
}
标签:子串,字符,charAt,重复,res,右移,Substring,Without,Longest
From: https://www.cnblogs.com/torry2022/p/17922297.html