209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的
子数组
[numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4] 输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1] 输出:0
提示:
1 <= target <= 1091 <= nums.length <= 1051 <= nums[i] <= 104
进阶:
- 如果你已经实现
O(n)时间复杂度的解法, 请尝试设计一个O(n log(n))时间复杂度的解法。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int sum = 0;
int first = 0;//子数组的起始位置
int result = Integer.MAX_VALUE;
for(int rear = 0;rear<nums.length;rear++) {//rear指子数组的终止位置
sum += nums[rear];
while(sum>=target) {
int l = rear-first+1;//子数组的长度
result = Math.min(l, result);//更新子数组长度
first++;//子数组的起始位置向后移动,看是否有长度更短的子数组
sum -= nums[first];//起始位置向后一位,删除一个元素
}
}
return result==Integer.MAX_VALUE?0:result;
}
}
76.最小覆盖子串
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:
- 对于
t中重复字符,我们寻找的子字符串中该字符数量必须不少于t中该字符数量。 - 如果
s中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC" 输出:"BANC" 解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。
示例 2:
输入:s = "a", t = "a" 输出:"a" 解释:整个字符串 s 是最小覆盖子串。
示例 3:
输入: s = "a", t = "aa" 输出: "" 解释: t 中两个字符 'a' 均应包含在 s 的子串中, 因此没有符合条件的子字符串,返回空字符串。
提示:
m == s.lengthn == t.length1 <= m, n <= 105s和t由英文字母组成
进阶:你能设计一个在 o(m+n) 时间内解决此问题的算法吗?
class Solution {
public String minWindow(String s, String t) {
char[] schar = s.toCharArray();
char[] tchar = t.toCharArray();
Map<Character,Integer> map = new HashMap<>();//记录所需的字符以及数量
for(int i = 0;i<tchar.length;i++) {
map.put(tchar[i], map.getOrDefault(tchar[i], 0)+1);
}
int num = map.keySet().size();//记录所需字符的种类数
String ans="";
int left = 0;
int right;
int anslen = 100001;
for(right = 0;right<schar.length;right++) {
if(map.containsKey(schar[right])) {
map.put(schar[right],map.get(schar[right])-1);
if(map.get(schar[right])==0) {
num--;
}
}
//所需字符都满足
if(num==0) {
//看删掉最左的字符之后是否也满足,满足就移动左指针
while(left<=right) {
if(map.containsKey(schar[left])==false) {
left++;
}else{
if(map.get(schar[left])+1<=0) {
map.put(schar[left], map.get(schar[left])+1);
left++;
}else {
break;
}
}
}
if(right-left+1<anslen) {
ans = s.substring(left, right+1);//endindex要写字符串的末尾
anslen = right-left+1;
}
}
}
return ans;
}
}
202

被折叠的 条评论
为什么被折叠?



