本文最后更新于:2025-01-20T21:44:56+08:00
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
1 2 3
| 输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
|
示例 2:
1 2 3
| 输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
|
示例 3:
1 2 3 4
| 输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
|
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
题目思路
要点:
- 用 begin 和 end 表示子串开始和结束位置
- 用 hash 表检查重复字符「key:字符,value:字符下标」
- 从左向右查看每个字符, 如果:
- 没遇到重复字符,调整 end++
- 遇到重复的字符,调整 begin(调整begin到重复字符的下一位,如果重复字符的下一位<begin,则仍然取begin,因为begin不可能倒退)
- 将当前字符放入 hash 表,hash表的键表示当前字符,值表示当前字符的索引
- end - begin + 1 是当前子串长度
题目代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
public int lengthOfLongestSubstring(String s) { if (s == null || s.isEmpty()) { return 0; } int right = 0; int max = 0; LinkedList<Character> list = new LinkedList<>(); while (right < s.length()) { char c = s.charAt(right); while (list.contains(c)) { list.removeFirst(); } list.addLast(c); right++; max = Math.max(list.size(), max); } return max; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public int lengthOfLongestSubstring(String s) { Map<Character, Integer> map = new HashMap<>(); int begin = 0; int maxLength = 0; for (int end = 0; end < s.length(); end++) { char ch = s.charAt(end); if (map.containsKey(ch)) { begin = Math.max(begin, map.get(ch) + 1); map.put(ch, end); } else { map.put(ch, end); } maxLength = Math.max(maxLength, end - begin + 1); } return maxLength; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public int lengthOfLongestSubstring2(String s) { int[] map = new int[128]; Arrays.fill(map, -1); int begin = 0; int maxLength = 0; for (int end = 0; end < s.length(); end++) { char ch = s.charAt(end); if (map[ch] != -1) { begin = Math.max(begin, map[ch] + 1); map[ch] = end; } else { map[ch] = end; } maxLength = Math.max(maxLength, end - begin + 1); } return maxLength; }
|
8.无重复字符的最长子串
http://example.com/2025/01/20/008-无重复字符的最长子串/