|
| 1 | +/* |
| 2 | +209. 长度最小的子数组 |
| 3 | +难度:中等 |
| 4 | +题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/ |
| 5 | +
|
| 6 | +给定一个含有 n 个正整数的数组和一个正整数 target 。 |
| 7 | +找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。 |
| 8 | +
|
| 9 | +示例 1: |
| 10 | +输入:target = 7, nums = [2,3,1,2,4,3] |
| 11 | +输出:2 |
| 12 | +解释:子数组 [4,3] 是该条件下的长度最小的子数组。 |
| 13 | +
|
| 14 | +示例 2: |
| 15 | +输入:target = 4, nums = [1,4,4] |
| 16 | +输出:1 |
| 17 | +
|
| 18 | +示例 3: |
| 19 | +输入:target = 11, nums = [1,1,1,1,1,1,1,1] |
| 20 | +输出:0 |
| 21 | +
|
| 22 | +提示: |
| 23 | +1 <= target <= 109 |
| 24 | +1 <= nums.length <= 105 |
| 25 | +1 <= nums[i] <= 105 |
| 26 | +
|
| 27 | +进阶: |
| 28 | +如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。 |
| 29 | +*/ |
| 30 | + |
| 31 | +import { fileURLToPath } from 'url' |
| 32 | +import testCases from '../tests/testCases/209_minimumSizeSubarraySum.js' |
| 33 | + |
| 34 | +/** |
| 35 | + * 长度最小的子数组 |
| 36 | + * - LeetCode 入口 |
| 37 | + * @param {number} target - 要大于或等于的正整数 |
| 38 | + * @param {number[]} nums - 整数数组 |
| 39 | + * @returns {number} 相加大于等于目标整数的最小子数组的长度 |
| 40 | + */ |
| 41 | +export function minSubArrayLen (target: number, nums: number[]): number { |
| 42 | + // 使用无限初始化返回值,在之后的操作中要判断子数组长度是否比返回值要小 |
| 43 | + let result: number = Infinity |
| 44 | + // 初始化子数组每个元素相加的值 |
| 45 | + let sum: number = 0 |
| 46 | + |
| 47 | + // 使用滑动窗口算法,初始化滑动窗口的起止下标为 0 |
| 48 | + // 每一次循环将窗口的右指针(结束指针)加一(向右移动一位),直到移动到整个数组的末位 |
| 49 | + for (let leftIndex = 0, rightIndex = 0; rightIndex < nums.length; rightIndex++) { |
| 50 | + // 每一次循环中将右指针所在的值累计相加 |
| 51 | + sum += nums[rightIndex] |
| 52 | + |
| 53 | + // 遇到子数组相加的值达到目标值 |
| 54 | + // 计算子数组长度,用更小的长度替换 result |
| 55 | + // sum 减去当前子数组左指针(起始指针)所在的值 |
| 56 | + // 将左指针加一(向右移动一位),缩小窗口范围,继续判断更小的窗口中的值相加是否能满足目标 |
| 57 | + while (sum >= target) { |
| 58 | + const subArrayLength = rightIndex - leftIndex + 1 |
| 59 | + if (subArrayLength < result) result = subArrayLength |
| 60 | + sum -= nums[leftIndex] |
| 61 | + leftIndex++ |
| 62 | + } |
| 63 | + } |
| 64 | + |
| 65 | + // 如果经历操作后返回值依然为初始的无限,则说明整个 nums 的值相加也无法满足目标,按要求返回 0 |
| 66 | + // 否则返回操作中找到的最小子数组长度 |
| 67 | + return result === Infinity ? 0 : result |
| 68 | +} |
| 69 | + |
| 70 | +// Debug |
| 71 | +if (process.argv[1] === fileURLToPath(import.meta.url)) { |
| 72 | + const { input, expected } = testCases[0] |
| 73 | + const output = minSubArrayLen(input.target, input.nums) |
| 74 | + console.log({ input, output, expected }) |
| 75 | +} |
0 commit comments