例1:最小连续子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0,如:
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
可以使用滑动窗口法求解:
维持一个窗口,每次计算窗口的值是否满足要求
import org.omg.PortableInterceptor.INACTIVE;
import javax.sound.midi.Soundbank;
import javax.swing.*;
import java.io.IOException;
import java.util.*;
public class Main {
// private LinkedList<>
private static Integer maxCount = 0;
public static void main(String[] args){
Integer[] arr = {2,3,1,2,4,3};
System.out.println(minSubArrayLen(7,arr));
}
public static int minSubArrayLen(int s, Integer[] nums) {
int start = 0;
int end = -1;
int minLen = nums.length + 1; //最小长度
int sum = 0; //和
while (start < nums.length){
//每次循环生成一个新的窗口
if (sum < s && end+1 < nums.length){
sum = sum + nums[++end];
}else {
sum = sum - nums[start++];
}
//计算新窗口的值
if (sum >= s){
if ((end - start + 1) < minLen){
minLen = end - start + 1;
}
}
}
if (minLen == nums.length + 1){
return 0;
}
return minLen;
}
}
例2:找到字符串中所有字母异位词(leetcode 438)
给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
说明:
- 字母异位词指字母相同,但排列不同的字符串。
- 不考虑答案输出的顺序。
示例 1:
输入: s: “cbaebabacd” p: "abc"
输出: [0, 6]
解释: 起始索引等于 0 的子串是 “cba”, 它是 “abc” 的字母异位词。 起始索引等于 6 的子串是 “bac”, 它是
“abc” 的字母异位词。
示例 2:
输入: s: “abab” p: "ab"
输出: [0, 1, 2]
解释: 起始索引等于 0 的子串是 “ab”, 它是 “ab” 的字母异位词。 起始索引等于 1 的子串是 “ba”, 它是 “ab”
的字母异位词。 起始索引等于 2 的子串是 “ab”, 它是 “ab” 的字母异位词。
使用滑动窗口法
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> res = findAnagrams("cbaebabacd","abc");
for (Integer v : res){
System.out.println(v);
}
}
public static int[] copyList(int[] list){
int[] copyList = new int[list.length];
for (int i=0; i<list.length; i++){
copyList[i] = list[i];
}
return copyList;
}
public static List<Integer> findAnagrams(String s, String p) {
int start = 0;
int end = -1;
int[] wordCount = new int[256];
List<Integer> ans = new LinkedList<Integer>();
for (int i=0; i<p.length(); i++){
wordCount[p.charAt(i)]++;
}
for (int i=0; i<wordCount.length; i++){
if (wordCount[i] == 0)
wordCount[i] = -1;
}
int[] tmpCount = copyList(wordCount);
while (start < s.length()){
if (tmpCount[s.charAt(start)] != -1){
if (end == -1){
end = start-1;
}
if (end+1<s.length() && tmpCount[s.charAt(end+1)]!=-1){
if (tmpCount[s.charAt(end+1)] > 0){
tmpCount[s.charAt(end+1)]--;
end++;
}else {
tmpCount[s.charAt(start)]++;
start++;
if (start > end){
end = -1;
}
}
}else {
tmpCount = copyList(wordCount);
start = end + 2;
end = -1;
}
}else {
start++;
}
if (end - start + 1 == p.length()){
ans.add(start);
}
}
return ans;
}
}