算法通关村第16关【白银】| 滑动窗口经典问题

1. 最长子串问题

(1)无重复字符的最长子串

算法通关村第16关【白银】| 滑动窗口经典问题_第1张图片

思路:窗口内为无重复字符子串,使用哈希表来保存最新碰到的字符下标,只要出现重复就缩小left指针,缩小到无重复字符也就是map.get(c)+1

class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashMap map = new HashMap();
        int l = 0;
        int r = 0;
        int len = s.length();
        int res = 0;
        while(r

(2)至多包含两个不同字符的最长子串

算法通关村第16关【白银】| 滑动窗口经典问题_第2张图片

思路:窗口为两个以内的不同字符,使用哈希表来保存最新碰到的字符下标,和上一题不同的是这里需要关注哈希表的size,如果超过2代表窗口内有两个以上不同的字符了,需要更新left指针位置为记录的窗口内最小的位置,并移除

public static int lengthOfLongestSubstringTwoDistinct(String s) {

        if (s.length() < 3) {
            return s.length();
        }
        int left = 0, right = 0;
        HashMap hashmap = new HashMap<>();
        int maxLen = 2;

        while (right < s.length()) {

            if (hashmap.size() < 3)
                hashmap.put(s.charAt(right), right++);

            // 如果大小达到了3个
            if (hashmap.size() == 3) {
                // 最左侧要删除的位置
                int del_idx = Collections.min(hashmap.values());
                hashmap.remove(s.charAt(del_idx));
                // 窗口left的新位置
                left = del_idx + 1;
            }

            maxLen = Math.max(maxLen, right - left);
        }
        return maxLen;
    }

(3)至多包含k个不同字符的最长子串

题目:给定一个字符串 s,找出 至多 包含 k 个不同字符的最长子串T

思路:只需要将上一题的3改成k,完美移植

public static int lengthOfLongestSubstringKDistinct(String s, int k) {
        if (s.length() < k + 1) {
            return s.length();
        }

        int left = 0, right = 0;
        HashMap hashmap = new HashMap<>();
        int maxLen = k;

        while (right < s.length()) {

            if (hashmap.size() < k + 1)
                hashmap.put(s.charAt(right), right++);

            // 如果大小达到了k个
            if (hashmap.size() == k + 1) {
                //
                int del_idx = Collections.min(hashmap.values());
                hashmap.remove(s.charAt(del_idx));
                // 窗口left的新位置
                left = del_idx + 1;
            }

            maxLen = Math.max(maxLen, right - left);
        }
        return maxLen;
    }

2. 长度最小的子数组

算法通关村第16关【白银】| 滑动窗口经典问题_第3张图片

思路:当小于target时就不断扩大窗口,当大于等于target的时候就从l开始不断剔除元素

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int l = 0;
        int r = 0;
        int sum = 0;
        int min = Integer.MAX_VALUE;
        while(r=target){
                min = Math.min(min,r-l+1);
                sum -= nums[l++];
            }
            r++;
        }
        return min!=Integer.MAX_VALUE ? min : 0;
    }
}

3.盛水最多的容器

算法通关村第16关【白银】| 滑动窗口经典问题_第4张图片

算法通关村第16关【白银】| 滑动窗口经典问题_第5张图片

思路:这题和上面不同的地方在于,不是双指针从头开始慢慢增大窗口,而是从首尾开始缩小窗口

长板不动,因为长板往内移动是一定会变小容量的

短板内移,可能变大也可能变小还可能不变,遍历一遍取最大

class Solution {
    public int maxArea(int[] height) {
        int left = 0;
        int right = height.length-1;
        int low = Math.min(height[left],height[right]);
        int ability = 0;
        while(right > left){
            if(height[left]

4.寻找子串异位词

1)字符串的排列

算法通关村第16关【白银】| 滑动窗口经典问题_第6张图片

思路:窗口为子串大小,从s1的位置为初始窗口位置开始遍历,看看s2窗口内是不是与s1相等的

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        if(s1.length()>s2.length()){
            return false;
        }
       char[] c1 = new char[26];
       char[] c2 = new char[26];
       int left = 0;
       int right = s1.length();
        for(int i = 0;i

2)找到字符串中所有字母异位词

算法通关村第16关【白银】| 滑动窗口经典问题_第7张图片

思路:和上一题差不多,窗口为子串大小,从子串大小位置为初始窗口位置开始遍历

class Solution {
    public List findAnagrams(String s, String p) {
        if(s.length()();
        }
         char[] c1 = new char[26];
       char[] c2 = new char[26];
       int left = 0;
       int right = p.length();
        for(int i = 0;i list = new ArrayList<>();
        if(Arrays.equals(c2,c1)){
            list.add(0);
        }
        while(right

你可能感兴趣的:(算法,算法,leetcode,数据结构)