首页 > 其他分享 >LeetCode | 209 MinimumSizeSubarraySum

LeetCode | 209 MinimumSizeSubarraySum

时间:2024-08-01 14:08:03浏览次数:15  
标签:right target nums 209 int result 数组 LeetCode MinimumSizeSubarraySum

分析

本题中是找与target相符的最小连续的子数组和,找一个能够容纳target这么大的最小子区间。虽然本节引入了滑动窗口的概念,可我更偏好于,这是一只毛毛虫在数组上的移动,找到最小的容纳自己位置的地方

  • target可看作毛虫本身的重量,数组中的每个元素值表示可承受的重量,right右指针看做毛虫的头,left左指针看做毛虫的尾巴
  • 在头部前进的过程中,扫过的连续元素累积和如果大于等于毛虫自身的重量,尾部便可以开始收缩前进,这时如果毛虫占据的数组空间无法承载毛虫的重量,毛虫的头部就要继续前进
  • 所以,两个循环,外部循环控制的是头部的移动,内部循环控制的是尾部的移动,内外循环其实只是毛虫在数组区间上的一次遍历
  • 在内循环中记录下遍历的最小子区间边界索引和最小长度

本节的核心其实还是在于遍历,双层for循环这种暴力破解确实可以做,主要还是target这个条件,给了我们一个更加明确的问题条件,用"滑动窗口/毛虫移动"解法就更优

主类

package com.github.dolphinmind.array;

/**
 * @author dolphinmind
 * @ClassName MinimumSizeSubarraySum
 * @description 209 长度最小的子数组
 * @date 2024/8/1
 */

public class MinimumSizeSubarraySum {

    /**
     * 毛毛虫移动的步伐,右指针是头,左指针是尾,循环结束双指针的目的就是遍历,内循环中获取最小子数组和的长度
     * 如何获取这个数组区间呢?
     * 在内循环中,如果sum大于等于target,则说明找到了一个满足题意的区间,此时需要更新result,同时更新区间的左右指针,
     * 通过比较最小子数组的大小,来给minIndex和maxIndex赋值,即确定了最小子区间
     * @param nums
     * @param target
     * @return
     */
    public int caterpillarMovement(int[] nums, int target) {

        if (nums.length == 0) {
            return -1;
        }

        int left   = 0;
        int right  = 0;

        int sum    = 0;
        int result = Integer.MAX_VALUE;

        int minIndex = 0;
        int maxIndex = 0;

        /**
         * 外循环控制滑动窗口的右指针
         */
        while (right < nums.length) {
            sum += nums[right];

            /**
             * 内循环控制滑动窗口的左指针,target就像是毛毛虫本身的分量
             */
            while (sum >= target) {
                int len = right - left + 1;

                if (len < result) {
                    result   = len;
                    minIndex = left;
                    maxIndex = right;
                }

                sum -= nums[left++];
            }

            right++;
        }

        printMinLenArray(nums, minIndex, maxIndex);

        return result == Integer.MAX_VALUE ? 0 : result;
    }

    /**
     * 打印最短子数组
     * @param nums
     * @param left
     * @param right
     */
    public void printMinLenArray(int[] nums, int left, int right) {
        System.out.print("[");

        while (left <= right) {
            System.out.print(nums[left++] + " ");
        }

        System.out.println("]");
    }
}

测试类

package com.github.dolphinmind.array;

import org.junit.Test;

/**
 * @author dolphinmind
 * @ClassName MinimumSizeSubarraySumTest
 * @description
 * @date 2024/8/1
 */

public class MinimumSizeSubarraySumTest {

    @Test
    public void test_caterpillarMovement() {
//        int[] nums = {2,3,1,2,4,3};
//        int[] nums = {};
        int[] nums = {1};
        int target = 7;

        MinimumSizeSubarraySum minimumSizeSubarraySum = new MinimumSizeSubarraySum();
        int res = minimumSizeSubarraySum.caterpillarMovement(nums, target);
        System.out.println("'毛虫移动/滑动窗口'获取最小和区间长度:" + res);
    }
}


解释

result初始值为什么控制这么大?

在滑动窗口算法中,将result的初始值设置为Integer.MAX_VALUE原因为了确保在算法执行过程中能够正确地更新result为找到的最小值

  • 避免初始值影响结果:如果初始值设置太小,可能会干扰算法找到真正的最小值
  • 确保正确更新:任何合法的数组长度都小于Integer.MAX_VALUE,算法在第一次找到符合条件的子数组时,无论这个子数组的长度是多少,都会更新result的长度
  • 处理无解情况:如果数组中没有任何子数组的和能够达到或超过target,return result == Integer.MAX_VALUE ? 0 : result;

标签:right,target,nums,209,int,result,数组,LeetCode,MinimumSizeSubarraySum
From: https://www.cnblogs.com/dolphinmind/p/18336530

相关文章

  • LeetCode 322 零钱兑换
    题目描述给你一个整数数组coins,表示不同面额的硬币;以及一个整数amount,表示总金额。计算并返回可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回-1。你可以认为每种硬币的数量是无限的。思路这是一个完全背包问题,背包问题当满足:物品不......
  • 每日一题:Leetcode-48 旋转图像
    力扣题目解题思路java代码力扣题目:给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转90度。你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。示例1:输入:matrix=[[1,2,3],[4,5,6]......
  • LeetCode 2024/8 每日一题合集
    2024-7-1LCP40.心算挑战代码实现classSolution{public:intmaxmiumScore(vector<int>&cards,intcnt){intn=size(cards);std::sort(cards.rbegin(),cards.rend());intsum=std::accumulate(cards.begin(),cards.begin()......
  • 两数之和(LeetCode题)
    题目:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。示例1:输入:nums=......
  • LeetCode 3111. 覆盖所有点的最少矩形数目(贪心、排序)
    题目:3111.覆盖所有点的最少矩形数目思路:只需关注横坐标,对横坐标进行升序排序,然后进行贪心,求得最少的矩阵数量classSolution{public:intminRectanglesToCoverPoints(vector<vector<int>>&points,intw){vector<int>v;for(inti=0;i<poi......
  • Leetcode每日一题 20240731 3111.覆盖所有点的最少矩阵数目
    题目描述给你一个二维整数数组point,其中points[i]=[xi,yi]表示二维平面内的一个点。同时给你一个整数w。你需要用矩形覆盖所有点。每个矩形的左下角在某个点(x1,0)处,且右上角在某个点(x2,y2)处,其中x1<=x2且y2>=0,同时对于每个矩形都必须满足x2......
  • leetcode20.有效的括号、华为OD机试-(C卷,100分)- 表达式括号匹配
    leetcode20.有效的括号题目描述给定一个只包括‘(’,‘)’,‘{’,‘}’,‘[’,‘]’的字符串s,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括号。示例1:输入:s=“()......
  • LeetCode | 27 RemoveElement
    https://github.com/dolphinmind/datastructure/tree/datastructure-array主类packagecom.github.dolphinmind.array.binarysearch;/***@authordolphinmind*@ClassNameRemoveElement*@description27移除元素*移除元素分析*快......
  • LeetCode | 977 SquaresOfASortedArray
    https://github.com/dolphinmind/datastructure/tree/datastructure-array主类packagecom.github.dolphinmind.array.binarysearch;/***@authordolphinmind*@ClassNameSquaresOfASortedArray*@description977.有序数组的平方*分析:有移除元素{......
  • LeetCode | 704 BinarySearch
    https://github.com/dolphinmind/datastructure/tree/datastructure-array主类packagecom.github.dolphinmind.array.binarysearch;/***@authordolphinmind*@ClassNameBinarySearch*@description704二分法搜索*前提条件:有序数组,且无重复元素......