0862:和至少为 K 的最短子数组(2306 分)
目录
题目
给你一个整数数组 nums
和一个整数 k
,找出 nums
中和至少为 k
的 最短非空子数组 ,并返回该子数组的长度。如果不存在这样的 子数组 ,返回 -1
。
子数组 是数组中 连续 的一部分。
示例 1:
输入:nums = [1], k = 1 输出:1
示例 2:
输入:nums = [1,2], k = 4 输出:-1
示例 3:
输入:nums = [2,-1,2], k = 3 输出:3
提示:
1 <= nums.length <= 105
-105 <= nums[i] <= 105
1 <= k <= 109
相似问题:
分析
#1
涉及到子数组的和,首先想到前缀和。得到前缀和数组 pre 后,问题转为: 求最小的 j-i 使得 pre[i]<=pre[j]-K。
暴力法就是遍历位置 j,在 pre[:j] 中找最大的满足要求的 i。
注意到如果 x < y 且 pre[x] >= pre[y],那么 y 比 x 更优,在后面的遍历中都可以排除 x。
因此可以维护一个严格递增的栈 stack,保存有用的位置和值。 然后就可以二分查找最大的 i 了。
|
|
时间复杂度 O(N*logN),728 ms
#2
还有个巧妙的想法。对于栈中的 i,当遍历到第一个 j 使得 pre[i]<=pre[j]-K,那么以 i 开头的最短子数组就是 pre[i:j+1],可以弹出 i 并更新结果。
因此,可以维护一个单调队列。
解答
|
|
时间复杂度 O(N),464 ms