长度最小的子数组[中等]

一、题目

给定一个含有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

::: warning
1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
:::

进阶: 如果你已经实现O(n)时间复杂度的解法, 请尝试设计一个O(n log(n))时间复杂度的解法。

二、代码

【1】滑动窗口: 定义两个指针fastslow分别表示子数组(滑动窗口窗口)的开始位置和结束位置,维护变量sum存储子数组中的元素和(即从nums[fast]nums[slow]的元素和)。初始状态下,fastslow都指向下标0sum的值为0。每一轮迭代,将nums[fast]加到 sum,如果sum≥target,则更新子数组的最小长度(此时子数组的长度是fast-slow+1,然后将nums[slow]sum中减去并将start右移,直到sum<target,在此过程中同样更新子数组的最小长度。在每一轮迭代的最后,将fast右移。

class Solution {public int minSubArrayLen(int target, int[] nums) {// 思路:1、指定快慢两个指针 fast slow // 2、fast 先移动,如果 sum > target , slow 先前走一步int fast = 0, slow = 0, sum = 0, min = Integer.MAX_VALUE;while (fast < nums.length) {sum += nums[fast];while (sum >= target) {min = Math.min(min, fast - slow + 1);sum-=nums[slow];++slow;}++fast;}return min == Integer.MAX_VALUE ? 0 : min;}
}

时间复杂度: O(n),其中n是数组的长度。指针fastslow最多各移动n次。
空间复杂度: O(1)

【2】前缀和 + 二分查找: 为了使用二分查找,需要额外创建一个数组sums用于存储数组nums的前缀和,其中sums[i]表示从nums[0]nums[i−1]的元素和。得到前缀和之后,对于每个开始下标i,可通过二分查找得到大于或等于i的最小下标index,使得sums[index]−sums[i−1]≥target,并更新子数组的最小长度(此时子数组的长度是index(i−1))。因为这道题保证了数组中每个元素都为正,所以前缀和一定是递增的,这一点保证了二分的正确性。如果题目没有说明数组中每个元素都为正,这里就不能使用二分来查找这个位置了。

在很多语言中,都有现成的库和函数来为我们实现这里二分查找大于等于某个数的第一个位置的功能,比如C++lower_boundJava中的Arrays.binarySearchC#中的Array.BinarySearchPython中的bisect.bisect_left。但是有时面试官可能会让我们自己实现一个这样的二分查找函数。

class Solution {public int minSubArrayLen(int target, int[] nums) {
return min == Integer.MAX_VALUE ? 0 : min;// 思路:1、新创建一个数组,保存i之前数据和;// 2、根据二分查找,获取到大于target的第一个下标;int[] sums = new int[nums.length + 1];int min = Integer.MAX_VALUE;for (int i = 1; i <= nums.length; i++) {sums[i] = sums[i - 1] + nums[i - 1];}for (int i = 1; i <= nums.length; i++) {int tarTemp = sums[i - 1] + target;int index = Arrays.binarySearch(sums, tarTemp);if (index < 0) {index = -index - 1;}// 找到了if (index <= nums.length) {min = Math.min(min, index - (i - 1));}}return min == Integer.MAX_VALUE ? 0 : min;}
}

时间复杂度: O(nlog⁡n),其中n是数组的长度。需要遍历每个下标作为子数组的开始下标,遍历的时间复杂度是O(n),对于每个开始下标,需要通过二分查找得到长度最小的子数组,二分查找得时间复杂度是O(log⁡n),因此总时间复杂度是O(nlog⁡n)
空间复杂度: O(n),其中n是数组的长度。额外创建数组sums存储前缀和。

【3】暴力解法: 初始化子数组的最小长度为无穷大,枚举数组nums中的每个下标作为子数组的开始下标,对于每个开始下标i,需要找到大于或等于i的最小下标j,使得从nums[i]nums[j]的元素和大于或等于s,并更新子数组的最小长度(此时子数组的长度是j−i+1)。

class Solution {public int minSubArrayLen(int target, int[] nums) {// 思路:1、定义返回值 res = max, 在循环中获取符合要求的最小长度,存入res中。求最小数时,返回值默认时 Integer的最大值;// 2、第一层for循环保证所有的数据都能够被遍历依次,作为left指针// 3、第二层for循环中,遍历left后的元素,找到第一个符合要求的子数组,也就是最小长度的子数组,直接退出;int res = Integer.MAX_VALUE;for(int i = 0; i < nums.length; i++) {// 第一层遍历之前需要重新定义int sum = 0;for(int j = i; j < nums.length; j++) {sum += nums[j];if (sum >= target) {res = Math.min(res, j - i + 1);break;}}}return res == Integer.MAX_VALUE ? 0 : res;}
}

时间复杂度: O(n2),其中n是数组的长度。需要遍历每个下标作为子数组的开始下标,对于每个开始下标,需要遍历其后面的下标得到长度最小的子数组。
空间复杂度: O(1)

【4】使用队列相加(实际上我们也可以把它称作是滑动窗口,这里的队列其实就相当于一个窗口): 我们把数组中的元素不停的入队,直到总和大于等于s为止,接着记录下队列中元素的个数,然后再不停的出队,直到队列中元素的和小于s为止(如果不小于s,也要记录下队列中元素的个数,这个个数其实就是不小于s的连续子数组长度,我们要记录最小的即可)。接着再把数组中的元素添加到队列中……重复上面的操作,直到数组中的元素全部使用完为止。
这里以[2,3,1,2,4,3]举例画个图来看下

上面画的是使用队列,但在代码中我们不直接使用队列,我们使用两个指针,一个指向队头一个指向队尾,我们来看下代码

public int minSubArrayLen(int s, int[] nums) {int lo = 0, hi = 0, sum = 0, min = Integer.MAX_VALUE;while (hi < nums.length) {sum += nums[hi++];while (sum >= s) {min = Math.min(min, hi - lo);sum -= nums[lo++];}}return min == Integer.MAX_VALUE ? 0 : min;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/656004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

迷你型洗衣机好用吗?迷你内裤洗衣机排名前十名推荐

随着大家工作的压力越来越大&#xff0c;下了班之后只能想躺平&#xff0c;在洗完澡之后看着还需要手洗的内衣裤真的很头疼。有些小伙伴还有会攒几天再丢进去洗衣机里面一起&#xff0c;而且这样子是非常不好的&#xff0c;用过的内衣裤长时间不清洗容易滋生细菌&#xff0c;而…

Redis学习——高级篇④

Redis学习——高级篇④ Redis7高级之Redis与Mysql数据双写一致性工程案例&#xff08;四&#xff09; 4.1 MySQL主从复制原理4.2 canal 工作原理4.3 mySQL->canal->redis 双写一致性1.环境2.配置Mysql3.配置canal4. Canal客户端&#xff08;Java编写&#xff0…

JavaScript-for循环的执行顺序

1.目标 掌握for执行顺序 2.实现思路 使用for循环输出0-到5 3.代码实现 Document 4.总结 for执行顺序 1.执行 var i 0 变量初始化 条件判断 是否成立 成立 执行循环体 不成立 退出for循环

STL_list

一、有关list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。Ii…

Docker容器引擎(6)

目录 一.什么是consul 解决什么问题&#xff1f; consul的模式&#xff1a; 二.consul 部署 consul服务器&#xff1a; 查看版本&#xff1a; 设置代理&#xff0c;在后台启动 consul 服务端&#xff1a; 进行后台启动&#xff1a; 查看集群信息&#xff1a; 访问页面…

云计算底层技术奥秘、磁盘技术揭秘、虚拟化管理、公有云概述

云计算基础 实验图例 虚拟化平台安装 创建虚拟机 1、创建虚拟机 2cpu&#xff0c;4G内存&#xff08;默认用户名: root 密码: a&#xff09; 2、验证 ecs 是否支持虚拟化 [rootecs ~]# grep -Po "vmx|svm" /proc/cpuinfovmx... ...[rootecs ~]# lsmod |grep kvm…

【算法专题】前缀和(附图解、代码)

&#x1f4d1;前言 本文主要是前缀和的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#xff1a;努力一点&…

Orion-14B-Chat-Plugin本地部署的解决方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

WebSocket 整合 记录用法

WebSocket 介绍 WebSocket 是基于tcp的一种新的网络协议,可以让浏览器 和 服务器进行通信,然后区别于http需要三次握手,websocket只用一次握手,就可以创建持久性的连接,并进行双向数据传输 Http和WebSocket的区别 Http是短连接,WebSocket’是长连接Http通信是单向的,基于请求…

互联网加竞赛 基于深度学习的人脸表情识别

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的人脸表情识别 该项目较…

HiveSQL题——排序函数(row_number/rank/dense_rank)

一、窗口函数的知识点 1.1 窗户函数的定义 窗口函数可以拆分为【窗口函数】。窗口函数官网指路&#xff1a; LanguageManual WindowingAndAnalytics - Apache Hive - Apache Software Foundationhttps://cwiki.apache.org/confluence/display/Hive/LanguageManual%20Windowin…

【Algorithms 4】算法(第4版)学习笔记 01 - 1.5 案例研究:union-find算法

文章目录 前言参考目录学习笔记1&#xff1a;动态连通性2&#xff1a;UF 实现 1&#xff1a;快速查找 quick-find2.1&#xff1a;demo 演示 12.2&#xff1a;demo 演示 22.3&#xff1a;quick-find 代码实现3&#xff1a;UF 实现 2&#xff1a;快速合并 quick-union3.1&#xf…

【Java 数据结构】二叉树

二叉树 1. 树型结构&#xff08;了解&#xff09;1.1 概念1.2 概念&#xff08;重要&#xff09;1.3 树的表示形式&#xff08;了解&#xff09;1.4 树的应用 2. 二叉树&#xff08;重点&#xff09;2.1 概念2.2 两种特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储2.5 二叉树的…

【人工智能课程】计算机科学博士作业二

使用TensorFlow1.x版本来实现手势识别任务中&#xff0c;并用图像增强的方式改进&#xff0c;基准训练准确率0.92&#xff0c;测试准确率0.77&#xff0c;改进后&#xff0c;训练准确率0.97&#xff0c;测试准确率0.88。 1 导入包 import math import warnings warnings.filt…

SpringBoot---创建项目

介绍 此项目SpringBoot使用的是2.6.1版本&#xff0c;由于这个项目使用的是maven聚合方式创建的&#xff0c;所以第二步是我在聚合方式下需要添加的依赖&#xff0c;完整的pom.xml内容放到了最下面。 第一步&#xff1a;创建Maven项目 这个里什么也不勾选&#xff0c;直接点…

JDK Locale的妙用:探索多语言和地区设置的强大功能

文章目录 前言应用场景国际化&#xff08;Internationalization&#xff09;格式化&#xff08;Formatting&#xff09;日期格式化数字格式化金额格式化百分比形式格式化 获取Locale信息 前言 JDK&#xff08;Java Development Kit&#xff09;的Locale类用于表示特定的地理、…

openGauss学习笔记-210 openGauss 数据库运维-常见故障定位案例-谓词下推引起的查询报错

文章目录 openGauss学习笔记-210 openGauss 数据库运维-常见故障定位案例-谓词下推引起的查询报错210.1 谓词下推引起的查询报错210.1.1 问题现象210.1.2 原因分析210.1.3 处理办法 openGauss学习笔记-210 openGauss 数据库运维-常见故障定位案例-谓词下推引起的查询报错 210.…

8-小程序数据promise化、共享、分包、自定义tabbar

小程序API Promise化 wx.requet 官网入口 默认情况下&#xff0c;小程序官方异步API都是基于回调函数实现的 wx.request({method: , url: , data: {},header: {content-type: application/json // 默认值},success (res) {console.log(res.data)},fail () {},complete () { }…

ANAPF有源电力滤波器选型计算——安科瑞赵嘉敏

配电系统中谐波电流的计算涉及很多因素。对于改造项目&#xff0c;可使用专业电能质量分析仪测得所需谐波数据&#xff1b;对于新建项目&#xff0c;设计人员并不能直接获得供电系统的的谐波数据&#xff0c;因此&#xff0c;我司研发人员通过众多不同行业、不同类型的项目&…

JSP仓储管理系统myeclipse定制开发SQLServer数据库网页模式java编程jdbc

一、源码特点 JSP仓储管理系统系统是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库 &#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为SQLServer2008&#x…