难度:中
问题描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
解题思路:滑动窗口
这类取子串问题,一般采用滑动窗口解决。滑动窗口应用在这道题上的解题思路:首先定义一个右节点,和一个左节点,但是左节点刚好可以被循环的i代替,左节点指向字符串0号下标,然后一直向右取不相同的值,直到取到相同的值后,停止。接着左指针右移一位,右节点又重新向右取不同值,直到相同,停下来。这每一轮移动过程的最后,当前产生的最大长度都要和上一轮的最大长度进行比较。最终比较出来的结果就是最长不重复子串。
代码:
public static int lengthOfLongestSubstring(String s) {
//用于存放已经读取的字符
HashSet<Character> set = new HashSet<>();
int n = s.length();
//rk为右节点
int rk = -1, ans = 0;
for (int i = 0; i < n; ++i) {
if (i != 0) {
//每一轮循环,左节点向右移一位
set.remove(s.charAt(i - 1));
}
//右节点只要下一次移动没超过字符串长度,并且指向内容没有重复,就执行右移操作
while (rk + 1 < n && !set.contains(s.charAt(rk + 1))) {
set.add(s.charAt(rk + 1));
++rk;
}
//比较当前轮次得出的最大长度,右指针减左指针加一(rk - i + 1)与原最大长度ans.
ans = Math.max(ans, rk - i + 1);
}
return ans;
}