题目:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:
输入: s = “”
输出: 0
思路:
假设我们选择字符串中第k个字符作为起始位置,并且获得了不包含重复最长子串的结束位置rk。当选择k+1作为起始位置,k+1到rk肯定是不包含重复字符的子串,那么我们增加rk的值变为rk+1。直到右侧出现重复字符,然后比较两个子串的长度。
- 使用两个指针表示左右边界,左指针代表枚举子串的起始位置,右指针为rk。
- 右指针不断向右移动一个字符,直到出现重复字符串为止,期间的子串代表着以左指针开始的,不包含重复字符的最长子串。
- 比较每一个子串的长度。
代码实现:
class Solution {
//给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
public int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<Character>();
int n = s.length();
//右指针
int rk = -1, count = 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的数字个数
count = Math.max(count, rk - i + 1);
}
return count;
}
}