接下来学习的知识是数组中的滑动窗口
还是按照之前的思路 先学习滑动窗口的思路
还是之前的哪个人的教程 我觉得很通俗易懂
滑动窗口就是这么神奇!mp.weixin.qq.com/s/ewCRwVw0h0v4uJacYO7htQ
紧接着做第一道题:
解题思路我都放在了程序里面
给定一个含有 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 <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
进阶:
如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//滑动窗口的初始位置 初始指针的位置
int startPointer = 0;//表示指针的初始位置从0序号开始
int sum = 0;//定义sum用来存储子数组的和
/**
* 刚开始定义的是0
* 后面结合后面的判断发现
* 如果是0的话不好进行最小子数组的判断
*/
int result = Integer.MAX_VALUE;//用于存储子数组的长度
//遍历数组 相当于快指针 前面定义的初始指针相当于慢指针
for(int fastPointer = 0;fastPointer<nums.length;fastPointer++){
sum += nums[fastPointer];
while(sum>=target){
//求得子数组的长度
int numsLength = fastPointer - startPointer + 1;//长度记得+1
result = numsLength<result?numsLength:result;
//相当于将左窗口的位置向前移动一位,然后得到移动后
//的子数组的大小
sum -= nums[startPointer++];
}
}
return result==Integer.MAX_VALUE?0:result;
}
}
在一排树中,第 i 棵树产生 tree[i] 型的水果。
你可以从你选择的任何树开始,然后重复执行以下步骤:
把这棵树上的水果放进你的篮子里。如果你做不到,就停下来。
移动到当前树右侧的下一棵树。如果右边没有树,就停下来。
请注意,在选择一颗树后,你没有任何选择:你必须执行步骤 1,然后执行步骤 2,然后返回步骤 1,然后执行步骤 2,依此类推,直至停止。
你有两个篮子,每个篮子可以携带任何数量的水果,但你希望每个篮子只携带一种类型的水果。
用这个程序你能收集的水果树的最大总量是多少?
示例 1:
输入:[1,2,1]
输出:3
解释:我们可以收集 [1,2,1]。
示例 2:
输入:[0,1,2,2]
输出:3
解释:我们可以收集 [1,2,2]
如果我们从第一棵树开始,我们将只能收集到 [0, 1]。
示例 3:
输入:[1,2,3,2,2]
输出:4
解释:我们可以收集 [2,3,2,2]
如果我们从第一棵树开始,我们将只能收集到 [1, 2]。
示例 4:
输入:[3,3,3,1,2,1,1,2,3,3,4]
输出:5
解释:我们可以收集 [1,2,1,1,2]
如果我们从第一棵树或第八棵树开始,我们将只能收集到 4 棵水果树。
提示:
1 <= tree.length <= 40000
0 <= tree[i] < tree.length
class Solution {
public int totalFruit(int[] fruits) {
if(fruits.length == 0){
return 0;
}
else if(fruits.length == 1){
return 1;
}
int Length = 0;//总量数组的s
int maxLength = 0;
int basket[] = {Integer.MAX_VALUE,Integer.MAX_VALUE};//定义两个篮子
//定义一个快指针 用于遍历数组
for (int startPointer = 0; startPointer < fruits.length-1; startPointer++) {
int endPointer = startPointer+1;
basket[0] = fruits[startPointer];
/**
* 一开始我是打算将全部都是一个小窗口(当前的数和他下一个数组成一个窗口)
* 但是还需要判断初始两端直接相等的情况
* 这一部分我还没有考虑很好
*/
for(int i= endPointer;i<fruits.length;i++){
if(basket[0]!=fruits[i]){
endPointer = i;
basket[1] = fruits[endPointer];
break;
}
else{
}
}
//判断窗口的结束位置右边的数有没有相同
for (int fastPointer = endPointer+1; fastPointer < fruits.length; fastPointer++) {
if(fruits[fastPointer] == basket[0]||fruits[fastPointer] == basket[1]){
endPointer++;//如果有那么窗口扩充
}
else{
break;
}
}
Length = endPointer - startPointer +1;
if(maxLength<Length){
maxLength = Length;
}
if(maxLength == fruits.length){//最长的直接结束
break;
}
//如果剩余的数组长度已经没有maxlength大 那么直接结束
if(startPointer>=fruits.length/2&&maxLength>=fruits.length){
break;
}
}
return maxLength;
}
}
这种方法的排名不高 我晚上看看别人的解题思路
参考别人的解题思路:
1.题目意思
每棵树只有1个水果。
找出连续子数组,一共2种水果,子数组长度最长。
2.思路
求最长子数组长度,直滑动窗口模板。
最长窗口模板
for(枚举选择)
右边界
while(不符合条件)
左边界
更新结果
思路:
本题中符合条件指窗口中水果种类是2。
用HashMap记录,Map<水果种类,出现频次>,
延伸右边界时,增加频次。缩进左边界时,减少频次。
频次为0时,从map删除。
map的大小为2时,正好符合条件。
这种套用模板的方式 算法的时间复杂度有所增加 但是空间复杂度降低了
class Solution {
public int totalFruit(int[] fruits) {
//对数组进行简单的判断 判断它是不是为null 或者 没有
if(fruits==null||fruits.length==0){
return 0;
}
int maxLength = 0;//定义最大的长度
int leftIndex = 0;//定义左边的边界
//定义篮子
/**
* 前面一个Interger保存树的编号
* 后面一个Interger保存同种类型的数量
*/
Map<Integer,Integer> basket= new HashMap<>();
//枚举选择
//有边界
for (int rightIndex = 0; rightIndex < fruits.length; rightIndex++) {
//判断在篮子里面是不是已经有了这种编号的树
basket.put(fruits[rightIndex], basket.getOrDefault(fruits[rightIndex], 0)+1);
while(basket.size()>2){
basket.put(fruits[leftIndex], basket.get(fruits[leftIndex])-1);//慢慢移动左边窗口
if(basket.get(fruits[leftIndex])==0) basket.remove(fruits[leftIndex]);
leftIndex++;
}
maxLength = Math.max(maxLength, rightIndex-leftIndex+1);
}
return maxLength;
}
}
字符串的题暂时不做
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
示例 2:
输入:s = "a", t = "a"
输出:"a"
示例 3:
输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。
提示:
1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?
总结:滑动窗口用于求解
最长子数组长度。
题目来源:
来源:力扣(LeetCode)
链接:力扣
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。