LeetCode[Hard]------Sliding Window类型题目详解

版权声明:版权归博主CodingArtist所有,转载请标明出处。 https://blog.csdn.net/sc19951007/article/details/83645949

什么是Sliding Window算法?

滑动窗口(Sliding Window)问题经常使用左边界(left)和右边界(right)来解决问题,[0, left) 的区域为滑动窗口已经探索过的区域, [left, right]的区域为滑动窗口正在探索的区域, (right, length-1)为待探索的区域。

Sliding Window的问题主要分为:
fixed size sliding window 和 dynamic size sliding window

fixed size sliding window: 正在探索的区域长度固定
non-fixed size sliding window: 正在探索的区域长度不固定

使用滑动窗口可以线性时间解决问题而且可以减少空间消耗。下面我结合LeetCode上的具体例子对Sliding Window算法进行分析。

LeetCode 159. Longest Substring with At Most Two Distinct Characters

问题描述

Given a string s , find the length of the longest substring t that contains at most 2 distinct characters.

Example 1:

Input: “eceba”
Output: 3
Explanation: t is “ece” which its length is 3.

Example 2:

Input: “ccaabbb”
Output: 5
Explanation: t is “aabbb” which its length is 5.

hashmap经典解法:

首先用hashmap存储string中的character,如果hashmap的size大于2,此时需要比较max,然后移动
window的左边界(start with 0),直到map中有character的frequency为0,此时删除 frequency为0的character,继续移动window的右边界,直到右边界到达最后一个character。


代码如下:

public int lengthOfLongestSubstringTwoDistinct(String s) {	
		HashMap<Character, Integer> map = new HashMap<>();
		int max = 0;
		int j = 0;
		for (int i = 0; i < s.length(); i++) {
			if(!map.containsKey(s.charAt(i))) {
				map.put(s.charAt(i), 1);
			}else {
				map.put(s.charAt(i), map.get(s.charAt(i))+1);
			}
			while(map.size() > 2) {
				map.put(s.charAt(j), map.get(s.charAt(j))-1);
				if(map.get(s.charAt(j)) == 0) {
					map.remove(s.charAt(j));
				}
				j++;
			}
			int temp = 0;
			for (int v : map.values()) {
				temp += v;
			};
			
			max = Math.max(max, temp);
		}
		return max;      
    }

LeetCode 340. Longest Substring with At Most K Distinct Characters

问题描述

Given a string, find the length of the longest substring T that contains at most k distinct characters.

Example 1:

Input: s = “eceba”, k = 2
Output: 3
Explanation: T is “ece” which its length is 3.

Example 2:

Input: s = “aa”, k = 1
Output: 2
Explanation: T is “aa” which its length is 2.

Sliding Window Speed up 解法:

因为英文字母有26个,所以定义一个int[],长度为256,因此其可以包含任意一个英文字符,不论大小写,我speed up就是用这个array去替换经典解法中hashmap的作用。


代码如下:

public int lengthOfLongestSubstringKDistinct(String s, int k) {
        int l = 0, cntDif = 0;
        int[] map = new int[256];
        int result = 0;

        for (int r = 0; r < s.length(); r++) {
            map[s.charAt(r)]++;
            if (map[s.charAt(r)] == 1) {
                cntDif++;
            }
            if (cntDif <= k) {
                result = Math.max(result, r - l + 1);
            }
            while (cntDif > k) {
                map[s.charAt(l)]--;
                if (map[s.charAt(l)] == 0) {
                    cntDif--;
                }
                l++;
            }
        }
        return result;
    }

效果如图


LeetCode 904. Fruit Into Baskets(From Google OA)

问题描述

In a row of trees, the i-th tree produces fruit with type tree[i].

You start at any tree of your choice, then repeatedly perform the following steps:

Add one piece of fruit from this tree to your baskets. If you cannot, stop.

  1. Move to the next tree to the right of the current tree. If there is no tree to the right, stop.
  2. Note that you do not have any choice after the initial choice of starting tree: you must perform step 1, then step 2, then back to step 1, then step 2, and so on until you stop.

You have two baskets, and each basket can carry any quantity of fruit, but you want each basket to only carry one type of fruit each.

What is the total amount of fruit you can collect with this procedure?

Example 1:

Input: [1,2,1]
Output: 3
Explanation: We can collect [1,2,1].

Example 2:

Input: [0,1,2,2]
Output: 3
Explanation: We can collect [1,2,2]. If we started at the first tree, we would only collect [0, 1].

Example 3:

Input: [1,2,3,2,2]
Output: 4
Explanation: We can collect [2,3,2,2]. If we started at the first tree, we would only collect [1, 2].

Example 4:

Input: [3,3,3,1,2,1,1,2,3,3,4]
Output: 5
Explanation: We can collect [1,2,1,1,2].
If we started at the first tree or the eighth tree, we would only collect 4 fruits.

Sliding Window 经典解法:

此题出自Google 的OA,完全可以参照之前的经典算法求解。

代码如下:

public int totalFruit(int[] tree) {
		HashMap<Integer, Integer> map = new HashMap<>();
		int max = 0;
		int j = 0;
		for (int i = 0; i < tree.length; i++) {
			if(!map.containsKey(tree[i])) {
				map.put(tree[i], 1);
			}else {
				map.put(tree[i], map.get(tree[i])+1);
			}
			while(map.size() > 2) {
				map.put(tree[j], map.get(tree[j])-1);
				if(map.get(tree[j]) == 0) {
					map.remove(tree[j]);
				}
				j++;
			}
			int temp = 0;
			for (int v : map.values()) {
				temp += v;
			};
			
			max = Math.max(max, temp);
		}
		return max;
    }
}

仅用于个人的学习理解,如需转载,请标明出处:
https://blog.csdn.net/sc19951007/article/details/83645949

猜你喜欢

转载自blog.csdn.net/sc19951007/article/details/83645949