java:滑动窗口 长度最小的子数组

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 <= 109
  • 1 <= nums.length <= 105
  • 1 <= 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.length
  • n == t.length
  • 1 <= m, n <= 105
  • s 和 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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值