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

一、题目

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构奇妙旅程之七大排序

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

如何做好阅读笔记搭建个人知识体系?

一、阅读笔记的重要性 阅读笔记在个人知识管理中扮演着重要的角色。通过记录、整理和利用阅读笔记&#xff0c;可以帮助我们更好地梳理个人知识体系&#xff0c;提高阅读效率&#xff0c;并且能够为个人成长提供有力支持。阅读笔记的重要性不言而喻&#xff0c;它是我们通过阅…

芯片替代查询指南:如何在电子设计中选择最佳替代方案

在电子制造与维修的世界里&#xff0c;芯片的选择和替代是一个常见且复杂的过程。选择正确的芯片替代对于确保电路的正常工作以及产品的性能不可或缺。本篇文章将为您提供关于芯片替代查询网站的全面指南。 什么是芯片替代查询&#xff1f; 芯片替代查询是提供芯片替代选项查…

时序数据库 Tdengine 执行命令能够查看执行的sql语句

curl是 访问6041端口&#xff0c;在windows系统里没有linux里的curl命令&#xff0c;需要用别的工具实现。我在cmd里是访问6030端口 第一步 在安装是时序数据库的服务器上也就是数据库服务端 进入命令窗口 执行 taos 第二步 执行 show queries\G;

OpenAI发布新模型!ChatGPT性能重磅提升,API大幅降价,GPT-4 「变懒」被修复

OpenAI 对ChatGPT进行了大更新&#xff1a;推出了新一代的嵌入模型&#xff0c;对GPT-4 Turbo模型进行了更新&#xff0c;并将很快对GPT-3.5 Turbo的API进行大幅降价&#xff0c;GPT-4「变懒」行为也被修复。 接下来二狗就带大家看看ChatGPT的这次详细更新。 推出新的嵌入模型…

PyQt5零基础入门(七)——文本编辑框

单行文本框控件(QLineEdit) QLineEdit是一个小部件&#xff0c;通常用于创建用户界面中的文本输入框。它提供了简单而强大的文本编辑功能&#xff0c;适用于各种需要单行文本输入的应用程序。 from PyQt5.QtWidgets import * import sysclass Window(QWidget):def __init__(s…

RK3568平台开发系列讲解(Linux系统篇)device 资源的获取

🚀返回专栏总目录 文章目录 一、platform_device 结构体二、platform_get_resource() 获取沉淀、分享、成长,让自己和他人都能有所收获!😄 一、platform_device 结构体 struct platform_driver 结构体继承了 struct device_driver 结构体, 因此可以直接访问 struct devi…

Python qt.qpa.xcb: could not connect to display解决办法

遇到问题&#xff1a;qt.qpa.xcb: could not connect to display 解决办法&#xff0c;在命令行输入&#xff1a; export DISPLAY:0 然后重新跑python程序&#xff0c;解决&#xff01; 参考博客&#xff1a;qt.qpa.xcb: could not connect to displayqt.qpa.plugin: Could …

Spring Boot + security + jwt 测试安全策略

一、测试概述 主要目的是测试security的用法。因测试搭建mysql和redis比较麻烦&#xff0c;所以我这里将自定义的jwt和用户信息缓存到程序的内存中。 本人测试的项目比较混乱&#xff0c;Spring Boot父类只标出有用的依赖。其子类用的版本为jdk11。后续会继续深入oauth2&#x…

【web安全】文件上传漏洞

upload-labs靶场 第一关 绕过前端 先打开哥斯拉&#xff0c;生成木马&#xff0c;选择php 打开brup开浏览器&#xff0c;上传文件&#xff0c;就会发现被阻止了&#xff0c;还没抓到包呢 那就是被前端代码阻止了&#xff0c;那通常前端代码都只能防御后缀名 我们抓到包后直…

分布式因果推断在美团履约平台的探索与实践

美团履约平台技术部在因果推断领域持续的探索和实践中&#xff0c;自研了一系列分布式的工具。本文重点介绍了分布式因果树算法的实现&#xff0c;并系统地阐述如何设计实现一种分布式因果树算法&#xff0c;以及因果效应评估方面qini_curve/qini_score的不足与应对技巧。希望能…

Android MediaCodec 简明教程(四):使用 MediaCodec 将视频解码到 Surface,并使用 SurfaceView 播放视频

系列文章目录 Android MediaCodec 简明教程&#xff08;一&#xff09;&#xff1a;使用 MediaCodecList 查询 Codec 信息&#xff0c;并创建 MediaCodec 编解码器Android MediaCodec 简明教程&#xff08;二&#xff09;&#xff1a;使用 MediaCodecInfo.CodecCapabilities 查…

微信小程序(二十五)条件判断语句与结构隐藏

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.条件判断语句的演示 2.隐藏结构的演示 源码&#xff1a; index.wxml <view><!-- wx:if和wx:else为条件判断语句 --><text wx:if"{{isLogin}}">已登入的用户</text><tex…

Flutter 应用服务:主题、暗黑、国际化、本地化-app_service库

Flutter应用服务 主题、暗黑、国际化、本地化-app_service库 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/det…

(一)PySpark3:安装教程及RDD编程(非常详细)

目录 一、pyspark介绍 二、PySpark安装 三、RDD编程 1、创建RDD 2、常用Action操作 ①collect ②take ③takeSample ④first ⑤count ⑥reduce ⑦foreach ⑧countByKey ⑨saveAsTextFile 3、常用Transformation操作 ①map ②filter ③flatMap ④sample ⑤d…

SQL报错注入

君衍. 一、sqllabs第五关报错注入updatexml报错注入原理及思路 二、常见的报错函数三、floor报错注入原理1、概念2、函数回顾2.1 rand函数2.2 floor(rand(0)*2)函数2.3 group by函数2.4 count(*)函数2.5 函数综合报错 3、报错分析4、总结 一、sqllabs第五关报错注入 之前我在这…

Linux系列之查看cpu、内存、磁盘使用情况

查看磁盘空间 df命令用于显示磁盘分区上的可使用的磁盘空间。默认显示单位为KB。可以利用该命令来获取硬盘被占用了多少空间&#xff0c;目前还剩下多少空间等信息。使用df -h命令&#xff0c;加个-h参数是为了显示GB MB KB单位&#xff0c;这样更容易查看 Filesystem …

使用Hugging Face下载ImageNet

1. 创建Hugging Face账号&#xff0c;在个人中心的setting部分&#xff0c;生成Access Token 2. 使用在python命令行中运行&#xff1a; pip install datasets 此时需要输入token 3. 新建一个python文件 from datasets import load_dataset dset load_dataset(imagenet-1k…

http-server开启一个服务器

前言 在写前端页面中&#xff0c;经常会在浏览器运行HTML页面&#xff0c;从本地文件夹中直接打开的一般都是file协议&#xff0c;当代码中存在http或https的链接时&#xff0c;HTML页面就无法正常打开&#xff0c;为了解决这种情况&#xff0c;需要在在本地开启一个本地的服务…

vuex store,mutations,getters,actions

文章目录 1.vuex概述2.构建vuex【多组件数据共享】环境Son1.vueSon2.vueApp.vue 3.创建一个空仓库4.如何提供&访问vuex的数据①核心概念 - state状态1.通过store直接访问2.通过辅助函数简化代码 ②核心概念 - mutations&#xff08;粗略&#xff09; 5.核心概念 - mutation…