力扣记录:209 长度最小的子数组及相关题目

本次题目

  • 209 长度最小的子数组
  • 904 水果成篮
  • 76 最小覆盖子串

209 长度最小的子数组

  • 暴力法;
  • 滑动窗口:也是双指针(起始指针和结束指针),如果当前窗口和大于目标值则移动起始指针;如果当前窗口和小于目标值则移动结束指针。
  • 注意:定义一个无限大的数作为初始值:Integer.MAX_VALUE。
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int leftFlag = 0;
        int sum = 0;
        int length = 0;
        int result = 10001;
        for(int rightFlag =0; rightFlag < nums.length; rightFlag++){
            sum += nums[rightFlag];
            while(sum >= target){
                length = rightFlag - leftFlag + 1;
                result = result < length ? result : length;
                sum -= nums[leftFlag];
                leftFlag++;
            }
        }
        return result == 10001 ? 0 : result;
    }
}

904 水果成篮

  • 滑动窗口:
  • 定义HashMap存储篮子,键值为存储的水果:该水果最后出现的位置;
  • 左指针指向第一种水果出现的第一个位置(窗口的左边界),右指针向前滑动,指向第二种水果出现的最后位置(窗口的右边界);
  • 当还有篮子时往HashMap里加水果,当超过两个篮子时左指针向前滑动,依次指向前两种水果,哪种水果的最后位置靠前就移除。
  • 注意:理解题目意思(连续的子序列!)输入为[1,0,1,4,1,4,1,2,3]时需要移除0而不是移除1!
  • 复习:HashMap,无序,不重复,无索引的键值对,size()、put、get、remove。
class Solution {
    public int totalFruit(int[] fruits) {
        Map<Integer, Integer> basket = new HashMap<>();
        int leftFlag = 0;
        int result = 0;
        int length = 0;
        for(int rightFlag = 0; rightFlag < fruits.length; rightFlag++) {
            if(basket.size() <= 2){
                basket.put(fruits[rightFlag], rightFlag);
            }
            while(basket.size() > 2){
                if(basket.get(fruits[leftFlag]) == leftFlag){
                    basket.remove(fruits[leftFlag]);
                }
                leftFlag++;
            }
            length = rightFlag - leftFlag + 1;
            result = Math.max(result, length);
        }
        return result;
    }
}

76 最小覆盖子串

  • 滑动窗口:
  • 定义HashMap存储目标字符及所需个数,键值为字符:字符个数,同时定义标志变量为HashMap长度确定总共需要的字符类别个数;
  • 定义左指针为字符开头,右指针向前遍历滑动,如果指向字符为目标字符,则HashMap中对应目标字符个数减一,当减为0时说明窗口内该目标字符满足条件;
  • 若标志变量也满足,则说明窗口内所有目标字符满足条件,此时滑动左指针,滑动条件为:左指针指向的字符不是目标字符,或者左指针指向字符是目标字符但超出要求个数。滑动后若窗口长度更短则截取窗口内字符。
  • 注意:既要判断每个字符是否满足要求(进入while,滑动左指针的条件),也要判断所有字符是否满足要求(while终止,停止滑动左指针的条件)
  • 复习:字符串处理StringBuilder,可以同步访问字符串(不是线程安全的),charAt、substring。
class Solution {
    public String minWindow(String s, String t) {
                StringBuilder s1 = new StringBuilder(s);
        StringBuilder t1 = new StringBuilder(t);
        Map<Character, Integer> basket = new HashMap<>();
        int leftFlag = 0;
        int length = Integer.MAX_VALUE;
        String result = "";
        // 先将需要寻找的字符串拆成每个字符放入篮子中,键值为字符:字符个数。
        for(int i = 0; i < t1.length(); i++){
            if(basket.containsKey(t1.charAt(i))){//如果篮子中存在该字符则个数加一
                Integer num = basket.get(t1.charAt(i)) + 1;
                basket.put(t1.charAt(i), num);
            }else{// 如果篮子中不存在该字符则添加该字符,个数为1
                basket.put(t1.charAt(i), 1);
            }
        }
        int flag = basket.size();
        int flagInBasket = 0;
        // 右指针向前滑动遍历
        for(int rightFlag = 0; rightFlag < s1.length(); rightFlag++){
            // 碰到目标字符则将篮子中对应字符个数减一
            if(basket.containsKey(s1.charAt(rightFlag))){
                int num = basket.get(s1.charAt(rightFlag)) - 1;
                basket.put(s1.charAt(rightFlag), num);
                if(num == 0){// 某个目标字符个数满足要求时篮中标志加一
                    flagInBasket++;
                }
            }
            if(flag == flagInBasket){//当篮中标志与总标志相等时截取字符
                // 左指针向前滑动分为两种情况:
                // (1)左指针指向的字符不是目标字符;
                // (2)左指针指向字符是目标字符但超出要求个数
                while(!basket.containsKey(s1.charAt(leftFlag))||
                        (basket.containsKey(s1.charAt(leftFlag))
                                &&basket.get(s1.charAt(leftFlag))<0)){
                    if (basket.containsKey(s1.charAt(leftFlag))) {
                        int num = basket.get(s1.charAt(leftFlag)) + 1;
                        basket.put(s1.charAt(leftFlag), num);
                    }
                    leftFlag++;
                }
                //对比字符长度得到最短字符
                if(length > (rightFlag-leftFlag+1)){
                    length = (rightFlag-leftFlag+1);
                    result = s1.substring(leftFlag, rightFlag+1);
                }
            }
        }
        return result;
    }
}

你可能感兴趣的:(算法,java,力扣)