LeetCode 3. Longest Substring Without Repeating Characters 无重复字符的最长子串(Java)

题目:

Given a string, find the length of the longest substring without repeating characters.

Example 1:
Input: “abcabcbb”
Output: 3
Explanation: The answer is “abc”, with the length of 3.

Example 2:
Input: “bbbbb”
Output: 1
Explanation: The answer is “b”, with the length of 1.

Example 3:
Input: “pwwkew”
Output: 3
Explanation: The answer is “wke”, with the length of 3.
Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

解答:

本题运用了滑动窗算法的思路,其中:

  1. 使用了双指针 left,right,分别代表当前窗口的起始和结束位置,
  2. 用hashset记录当前窗口中存在的字符元素
  3. 整体思路是保持窗口起始处(左指针 left)固定不变,移动窗口结束处(右指针 right)。若当前窗口结束处(右指针 right 所指)字符未出现在 hashset 中,则该字符不重复,更新 result 结果值并继续右移窗口结束处(右指针 right)。若当前窗口结束处(右指针 right 所指)字符已出现在 hashset 中,则从 hashset 中移除窗口起始处(左指针 left 所指)字符,右移 left ,并继续判断右指针 right 是否重复(右指针 right 可能与当前窗口中的某字符重复,所以需要多次判断,直至删除掉重复字符,保持 set 中字符唯一性)
  4. 每次更改窗口结束处(右指针 right )时,都更新 result 的值,取更新后长度与上次长度的最大值
class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashSet<Character> set = new HashSet<>();
        int left = 0;
        int right = 0;
        int result = 0;
        while(left<s.length() && right<s.length()) {
            if(!set.contains(s.charAt(right))) {
                set.add(s.charAt(right));                
                result = Math.max(result,right-left+1);
                right++;
            }else {
                set.remove(s.charAt(left));
                left++;
            }
        }
        return result;
    }
}

滑动窗口思想

滑动窗口是一种常用到的解题思想。

一般是基于双指针进行求解,对数组或者字符串进行遍历时,两个指针一前一后夹着子数组或子串,从而确定一个窗口,通过控制前后指针的移动,来控制窗口的大小和范围。通常也会用到一些特定的数据结构,如 hashmap 等。

解题的大体思路:先保持左指针不动,移动右指针,右指针每往前移动一格,都会有新一个元素进入窗口,这时条件可能就会发生改变,然后根据当前条件来决定左指针是否移动,以及移动多少格。具体问题基于以上具体求解即可

如本题中例 3 的滑动窗口的滑动遍历过程,[ ] 分别表示窗口的起始和结束位置

[ p w ] w k e w
[ p w  w ] k e w
p [ w  w ] k e w
p w [ w ] k e w
p w [ w k ] e w
p w [ w k e ] w
p w [ w k e w ]
p w w [ k e w ]

常见的应用场景:通常应用于主数组和子数组,或主串和子串的关系问题
如:

  • 最小覆盖子串(给你一个字符串 S,一个字符串 T,请在字符串 S 里面找出包含 T 所有字母的最小子串),具体见 LeetCode 第 76 题
  • 长度最小的子数组(给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组),具体见 Leetcode 第 209 题
  • 替换后的最长重复字符,具体见 LeetCode 第 424 题
  • 找到字符串中所有字母异位词,具体见 LeetCode 第 438 题
  • 字符串的排列,具体见 LeetCode 第 567 题

你可能感兴趣的:(LeetCode)