力扣209(java&python)-长度最小的子数组(中等)
题目:
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
提示:
1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
进阶:
如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-size-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
一、【前缀和+二分查找】
前缀和:sum[i]表示从nums[0]到nums[i-1]的元素和。本题中说明了每个元素都为正,所以前缀和一定是递增的。
- 首先预处理出前缀和数组sum,前缀和数组下标从1开始,sum[i] = sum[i - 1] + nums[i - 1];
- 假设s对应的前缀和为:s = sum[i+1]=sum[i] + nums[i],将nums[i]视为结果数组的右端点,现在问题转换为找结果数组的左端点,已知s和target,题目要求是要找到大于等于target的最小数组长度,于是可以转换成在前缀和数组下标[0,i]中内找到满足小于等于d = s - target的最大下标,这个最大下标就是结果数组的左端点。
注意:
代码中更新最短长度用的:i - left,为什么没有写成 i - left+ 1?
因为前缀和下标从1开始的,而left是从下标0开始的。故相减下来就是数组的长度。
java代码:
1 class Solution {
2 public int minSubArrayLen(int target, int[] nums) {
3 int n = nums.length, ans = Integer.MAX_VALUE;
4 int[] sum = new int[n + 1];
5 //计算前缀和
6 for (int i = 1; i <= n; i++){
7 sum[i] = sum[i - 1] + nums[i - 1];
8 }
9 for (int i = 1; i <= n; i++){
10 int s = sum[i], d = s - target;
11 int left = 0, right = i;
12 while (left < right){
13 int mid = left + (right - left + 1) / 2;
14 //不够d,需要往右移
15 if (sum[mid] <= d){
16 left = mid;
17 }else{
18 //超过了d,往左移
19 right = mid - 1;
20 }
21 }
22 //循环结束:left == right,找到小于等于d的最大下标,更新最小长度
23 if (sum[left] <= d){
24 ans = Math.min(ans, i - left);
25 }
26 }
27 return ans == Integer.MAX_VALUE ? 0 : ans;
28 }
29 }
二、【滑动窗口】--双指针
滑动窗口需要考虑的三点:
1.窗口内是什么?
2.怎么移动窗口的起始位置?
3.怎么移动窗口的结束位置?
然后本题就是:
1.窗口内就是 满足其和 ≥ s 的长度最小的 连续 子数组。
2.窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
3.窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
关键部分图解:
来源:代码随想录
复杂度:
主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。
java代码:
1 class Solution {
2 public int minSubArrayLen(int target, int[] nums) {
3 int n = nums.length, ans = Integer.MAX_VALUE;
4 int left = 0, sublen = 0, sum = 0;
5 for (int right = 0; right < n; right++){
6 sum += nums[right];
7 while (sum >= target){
8 //获取当前数组长度
9 sublen = right - left + 1;
10 ans = Math.min(ans, sublen);
11 sum -= nums[left++];
12 }
13 }
14 return ans == Integer.MAX_VALUE ? 0 : ans;
15 }
16 }
python3代码:
1 class Solution:
2 def minSubArrayLen(self, target: int, nums: List[int]) -> int:
3 left, ans, sum, sublen = 0, float("inf"), 0, 0
4 for right in range(len(nums)):
5 sum += nums[right]
6 while sum >= target:
7 sublen = right - left + 1
8 ans = min(sublen, ans)
9 sum -= nums[left]
10 left += 1
11 return 0 if ans == float("inf") else ans
力扣209(java&python)-长度最小的子数组(中等)的更多相关文章
- 代码随想录训练营day 2 |977有序数组的平方 209.长度最小的子数组 (C++)
977.有序数组的平方 题目链接:977.有序数组的平方 题目描述:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序. 例子如下: 输入 ...
- 双指针之滑动窗口(长度最小的子数组 和 和为s的连续正数序列)
双指针之滑动窗口 (长度最小的子数组:和为s的连续正数序列) 1, 什么时候使用? (与子数组/字符串 有关的题目)~如果给了某个具体值的target,即用滑动窗口 不然就双指针(一般做法,左边< ...
- 209. 长度最小的子数组--LeetCode
来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/minimum-size-subarray-sum 著作权归领扣网络所有.商业转载请联系官方授权,非商业 ...
- 有序数组的平方&长度最小的子数组&螺旋矩阵Ⅱ
一.有序数组的平方 977.有序数组的平方 leetcode链接 1.方法概述 双"指针"解法:因为数组本来是有序的,平方后可能出现的两端大数值大的情况.所以从数组两端开始遍历,谁 ...
- [Swift]LeetCode209. 长度最小的子数组 | Minimum Size Subarray Sum
Given an array of n positive integers and a positive integer s, find the minimal length of a contigu ...
- 力扣1052. 爱生气的书店老板-C语言实现-中等难度
题目 传送门 文本 今天,书店老板有一家店打算试营业 customers.length 分钟.每分钟都有一些顾客(customers[i])会进入书店,所有这些顾客都会在那一分钟结束后离开. 在某些时 ...
- [LeetCode] 209. Minimum Size Subarray Sum 最短子数组之和
Given an array of n positive integers and a positive integer s, find the minimal length of a contigu ...
- Java实现 LeetCode 795 区间子数组个数 (暴力分析)
795. 区间子数组个数 给定一个元素都是正整数的数组A ,正整数 L 以及 R (L <= R). 求连续.非空且其中最大元素满足大于等于L 小于等于R的子数组个数. 例如 : 输入: A = ...
- 力扣(LeetCode)453. 最小移动次数使数组元素相等
给定一个长度为 n 的非空整数数组,找到让数组所有元素相等的最小移动次数.每次移动可以使 n - 1 个元素增加 1. 示例: 输入: [1,2,3] 输出: 3 解释: 只需要3次移动(注意每次移动 ...
- [Swift-2019力扣杯春季初赛]3. 最小化舍入误差以满足目标
给定一系列价格 [p1,p2...,pn] 和一个目标 target,将每个价格 pi 舍入为 Roundi(pi) 以使得舍入数组 [Round1(p1),Round2(p2)...,Roundn( ...
随机推荐
- C语言中的rand()函数实例分析
一 前记: c语言中需要用到随机值得时候,每次都自己写,这样太浪费效率了,这次遇到了一个经典的代码,就珍藏起来吧. 二 实例分析: 1 #include <stdio.h> 2 3 int ...
- C# 中的for/foreach循环
for 循环是一个执行特定次数的循环的重复控制结构. C# 中 for 循环的语法: for ( init; condition; increment ) { statement(s); } 执行流程 ...
- idea使用Mybatis Log查看执行的sql语句
参考,欢迎点击原文:https://www.jb51.net/article/195895.htm https://blog.csdn.net/qq2710393/article/details/83 ...
- Clang开发注意事项
Clang tools need their builtin headers and search for them the same way Clang does. Thus, the defaul ...
- 二.安装ifconfig命令
二.安装ifconfig命令 1.ifconfig命令是设置或显示网络接口的程序,可以显示出我们机器的网卡信息,可是有些时候最小化安装CentOS等Linux发行版的时候会默认不安装ifconfig等 ...
- STAR法则是什么(如何把一件事表达清楚)
STAR法则,即为Situation Task Action Result的缩写,具体含义是: Situation: 事情是在什么情况下发生 Task: 你是如何明确你的任务的 Action: 针对这 ...
- 禅道16.2版本发布!主要新增专业研发看板,修复Bug
大家好,禅道16.2发布了,本次发布在项目管理模型层面新增了专业研发看板功能,今后禅道全面支持Scrum.瀑布.看板3种项目管理模型,功能更加健全,用户选择更加灵活. 视频地址:https://www ...
- 创业:大模型RAG系统三个月的开发心得和思考
1. 前言 自从和员外上家公司离职后,我们就自己搞公司投入到了RAG大模型的AI产品应用的开发中,这中间有一个春节,前后的总时间大概是三个月左右,在这三个月期间,基本是昼夜兼程啊,到今天3月底结束,产 ...
- Jetty的http模块
启用http模块,执行如下命令: java -jar $JETTY_HOME/start.jar --add-modules=http 查看http模块的配置文件,执行如下命令: cat $JETTY ...
- OpenHarmony定义组件重用样式:@Styles装饰器
如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,我们推出了可以提炼公共样式进行复用的装饰器@Styles. @St ...