【每日一题Day8】LC862和至少为K的最短子数组
*和至少为K的最短子数组【LC862】
给你一个整数数组
nums
和一个整数k
,找出nums
中和至少为k
的 最短非空子数组 ,并返回该子数组的长度。如果不存在这样的 子数组 ,返回-1
。子数组 是数组中 连续 的一部分。
今天只能想到超时的做法,想到用单调栈却不知道怎么维护,看题解有C++用单调栈,再结合官题的双端队列,终于写出来了0.0
- 思路:将数组的前i个数字之和记为sum,如果数组中从第i+1个数字开始到第j个数字结束的子数组之和大于等于k,那么数组的前i个数字之和小于等于为sum-k。
- 如何快速搜索是否有前j个数字之和小于等于sum-k以及下标?
- 使用hashmap记录前j个数字之和以及下标,然后通过for循环遍历查找map中是否存在[minSum,sum-k]【超时】
- 单调栈+二分查找?->不能通过下标形式查找所需值,因此不能够实现
- 双端队列
- 如何快速搜索是否有前j个数字之和小于等于sum-k以及下标?
前缀和+暴力搜索【超时】
class Solution {public int shortestSubarray(int[] nums, int k) {int len = nums.length;int[] sums = new int[len+1];// 记录nums[0,i-1]的子数组和for (int i = 0; i < len; i++){sums[i+1] = sums[i] + nums[i];}int minLen = Integer.MAX_VALUE;for (int i = 0; i < len; i++){for (int j = i; j < len;j++){int subSum = sums[j+1] - sums[i];if (subSum >= k){minLen = Math.min(minLen,j - i + 1);}}}return minLen == Integer.MAX_VALUE ? -1 :minLen;}
}
- 复杂度
- 时间复杂度:最差O(n2)
- 空间复杂度:O(n)
前缀和+HashMap【超时】
实现:使用hashmap记录前j个数字之和以及下标,然后通过for循环遍历查找map中是否存在[minSum,sum-k]【超时】
代码
class Solution {public int shortestSubarray(int[] nums, int k) {Map<Integer,Integer> sumToIndex = new HashMap<>();sumToIndex.put(0,-1);int len = nums.length;int sum = 0;// 记录子数组nums[0,i]的和int minSum = 0;// 记录前i个子数组nums[0,i]和的最小值int minLen = Integer.MAX_VALUE;for (int i = 0; i < len; i++){sum += nums[i]; int target = sum - k;if (minSum <= target){// 存在前j个数字之和小于等于sum-kfor (int n = minSum; n <= target; n++){if (sumToIndex.containsKey(n)){minLen = Math.min(minLen,i - sumToIndex.get(n));}}} sumToIndex.put(sum,i);minSum = Math.min(minSum,sum);}return minLen == Integer.MAX_VALUE ? -1 :minLen;} }
复杂度
- 时间复杂度:最差O(n2)
- 空间复杂度:O(n)
前缀和+双端队列
实现:双端队列存储元素下标
从头部到尾部下标对应的前缀和的顺序为递增
当头部元素存储的下标i对应的前缀和sum[i]小于等于当前遍历的元素sums[j]-k时,更新minLen=min(minLen,j-i),并将其弹出
- 为什么弹出不影响后续结果?因为后续节点的j‘-i一定大于j-i,因此一定不会影响结果
当尾部元素存储的前缀和大于当前遍历的元素sums[j]时,将其弹出
- 我们需要保持队列递增
把sums[j]压入队列尾部,保证sums[j]是队列最大的元素
代码
class Solution {public int shortestSubarray(int[] nums, int k) {int len = nums.length;long[] sums = new long[len + 1];for (int i = 0; i < len; i++) {sums[i + 1] = sums[i] + nums[i];}int minLen = Integer.MAX_VALUE;Deque<Integer> st = new LinkedList<>();for (int i = 0; i <= len; i++){long curSum = sums[i];while (!st.isEmpty() && sums[st.peekFirst()] <= curSum - k ){minLen = Math.min(minLen,i-st.pollFirst());}while (!st.isEmpty() && curSum <= sums[st.peekLast()]){st.pollLast();}st.addLast(i);}return minLen == Integer.MAX_VALUE ? -1 :minLen;} }
复杂度
- 时间复杂度:O(n)
- 空间复杂度:O(n)
【每日一题Day8】LC862和至少为K的最短子数组相关推荐
- 【教3妹学算法-每日3题(3)】 和至少为 K 的最短子数组
插: 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到网站. 坚持不懈,越努力越幸运,大家一起学习鸭~~~ 3妹:小呀么小二郎呀, 背着那书包上学堂. 2 ...
- 算法/编程练习:寻找和至少为K的最短子数组
寻找和至少为K的最短子数组 1. 题目 题目来自LeetCode: https://leetcode-cn.com/problems/shortest-subarray-with-sum-at-lea ...
- 《有意思的题》和至少为 K 的最短子数组
问题: 力扣的第209道题209. 长度最小的子数组 - 力扣(LeetCode)很简单的滑动窗口,但是如果数组中有负数,那就有点麻烦了,例如力扣的第86道题862. 和至少为 K 的最短子数组 - ...
- LeetCode算法系列_0862_和至少为K的最短子数组
0862_和至少为 K 的最短子数组 题目描述 返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K . 如果没有和至少为 K 的非空子数组,返回 -1 . 示例1: 输入:A = [1], ...
- Leetcode-862. 和至少为 K 的最短子数组
题目链接:https://leetcode-cn.com/problems/shortest-subarray-with-sum-at-least-k/ 题目 给你一个整数数组 nums 和一个整数 ...
- ⭐算法入门⭐《队列 - 单调队列》困难03 —— LeetCode 862. 和至少为 K 的最短子数组
文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述 返回数组 AAA 的最 ...
- 和至少为k的最短子数组 python_LeetCode 862. 和至少为 K 的最短子数组
最近刷LeetCode题目的一些思路,题目信息 返回A 的最短的非空连续子数组的长度,该子数组的和至少为 K .如果没有和至少为 K 的非空子数组,返回 -1 . 示例 1:输入:A = [1], K ...
- 862. 和至少为 K 的最短子数组
862. 和至少为 K 的最短子数组 返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K . 如果没有和至少为 K 的非空子数组,返回 -1 . 示例 1: 输入:A = [1], K = ...
- 【862. 和至少为 K 的最短子数组】
来源:力扣(LeetCode) 描述: 给你一个整数数组 nums 和一个整数 k ,找出 nums 中和至少为 k 的 最短非空子数组 ,并返回该子数组的长度.如果不存在这样的 子数组 ,返回 ...
最新文章
- Mysql 客户端查询结果如何保存到本地而不是服务端?
- 在DropboxEdge网络上评估BBRv2
- 全国计算机等级考试题库二级C操作题100套(第65套)
- python模拟给qq发消息,python模拟QQ聊天--socket通信
- iOS: OC/Swift使用CocoaPods生成Podfile文件、安装第三方SDK
- 调用有道智云api做翻译器遇到播放音频的问题
- 牙齿变色怎么办?如何清洁牙齿?
- Java基于SpringBoot的牛客网社区项目实现详解(上)
- [ACM]【Dijkstra/DP】Atcoder 164 Two Currencies
- 通过用jQuery写一个页面,我学到了什么
- 软件测试自动化分类,自动化测试的主要分类
- 学习指针后对int main(int argc, char *argv[]),“()“内部参数的详解(初学者不要怕,浅浅学过指针的就可以看懂)
- Golang iota详解
- AE基础教程(7)——第7章 区域显示,透明网格
- 关于u盘插入电脑在我的电脑中不显示盘符无法正常使用,但是在右下角图标有显示的问题。
- STM32Cube配置等精度测频和测相位差
- 容联“扩容”,走出AI视觉场景落地之路
- Prometheus组件详解
- 惠普HP打印机卸载重装后驱动无法安装
- GDB调试指南-单步调试