https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
image.png

我的答案

  1. class Solution {
  2. public int lengthOfLongestSubstring(String s) {
  3. Map<Character, Integer> map = new HashMap<>();
  4. int left = 0, right = 0;
  5. int res = 0;
  6. while (right < s.length()) {
  7. char c = s.charAt(right);
  8. if (!map.containsKey(c) || map.get(c) < left) {
  9. res = Math.max(right - left + 1, res);
  10. } else {
  11. left = map.get(c) + 1;
  12. }
  13. map.put(c, right);
  14. right++;
  15. }
  16. return res;
  17. }
  18. }

image.png
双指针+哈希表方法,要注意一点map.get(c) < left,这个条件,当left指针向前跳跃时map中被跳过的key就失效了,不用真正删除map中的key,如果小于left说明失效。

最优解

  1. public int lengthOfLongestSubstring(String s) {
  2. int[] cache = new int[128];
  3. for (int i = 0; i < 128; i++) {
  4. cache[i] = -1;
  5. }
  6. int n = s.length();
  7. int res = 0;
  8. int left = 0;
  9. for (int i = 0; i < n; i++) {
  10. int index = s.charAt(i);
  11. if (cache[index] >= left) {
  12. left = cache[index] + 1;
  13. }
  14. res = Math.max(res, i - left + 1);
  15. cache[index] = i;
  16. }
  17. return res;
  18. }

image.png
用数组代替了map,作用是相同的,是提升速度的关键。另外,计算过程也更精简,关键是计算左边界。如果cache[index] >= left,说明子串中包含重复元素,需要跳跃。