至多包含两个不同字符的最长子串
难度:
标签:
题目描述
代码结果
运行时间: 135 ms, 内存: 16.4 MB
/*
* 思路:
* 1. Java Stream API 并不特别适合解决滑动窗口问题,因为它们主要用于集合操作。
* 2. 但是我们可以使用 stream 操作符对字符进行过滤和转换。
* 3. 使用基本的循环和 map 来记录字符的位置,并维护窗口的左右边界。
*/
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
import java.util.stream.IntStream;
public class Solution {
public int lengthOfLongestSubstringTwoDistinct(String s) {
if (s.length() < 3) return s.length();
Map<Character, Integer> hashmap = new HashMap<>();
int[] max_len = {2};
IntStream.range(0, s.length()).forEach(right -> {
hashmap.put(s.charAt(right), right);
if (hashmap.size() == 3) {
int del_idx = Collections.min(hashmap.values());
hashmap.remove(s.charAt(del_idx));
left = del_idx + 1;
}
max_len[0] = Math.max(max_len[0], right - left + 1);
});
return max_len[0];
}
private int left = 0;
}
解释
方法:
该题解使用滑动窗口的思路来解决问题。通过维护两个指针 x0 和 x1 分别记录窗口内最多两个不同字符的位置,同时用 y0 和 y1 记录对应的字符。每次遇到一个新字符时,根据情况更新 x0, x1, y0, y1 以及窗口的起始位置 srt,并更新最大长度 mx。最终返回 mx 即为所求的最长子串长度。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在这个算法中,如何确保在更新字符位置 x0 和 x1 时,始终保留窗口内最后出现的两个不同字符?
▷🦆
当出现新字符而需要更新窗口时,为什么选择将窗口起始位置 srt 设置为 x0 而不是 x1?
▷🦆
算法中的变量 y0 和 y1 分别用来做什么?它们是如何与 x0 和 x1 互动的?
▷🦆
在滑动窗口策略中,如果遇到的字符序列中只有一个种类的字符,这种情况下 srt, x0, x1 的值将如何变化?
▷相关问题
无重复字符的最长子串
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc"
,所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b"
,所以其长度为 1。
示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
滑动窗口最大值
给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 输出:[3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1 输出:[1]
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
K 个不同整数的子数组
给定一个正整数数组 nums
和一个整数 k
,返回 nums
中 「好子数组」 的数目。
如果 nums
的某个子数组中不同整数的个数恰好为 k
,则称 nums
的这个连续、不一定不同的子数组为 「好子数组 」。
- 例如,
[1,2,3,1,2]
中有3
个不同的整数:1
,2
,以及3
。
子数组 是数组的 连续 部分。
示例 1:
输入:nums = [1,2,1,2,3], k = 2 输出:7 解释:恰好由 2 个不同整数组成的子数组:[1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2].
示例 2:
输入:nums = [1,2,1,3,4], k = 3 输出:3 解释:恰好由 3 个不同整数组成的子数组:[1,2,1,3], [2,1,3], [1,3,4].
提示:
1 <= nums.length <= 2 * 104
1 <= nums[i], k <= nums.length