【数组】leetcode209.有序数组的平方(C/C++/Java/Js)

news2024/11/17 4:26:09

leetcode209.长度最小的子数组

  • 1 题目
  • 2 思路-滑动窗口
  • 3 代码
    • 3.1 C版本
    • 3.2 C++版本
    • 3.3 Java版本
    • 3.4 JavaScript版本
  • 4 总结

1 题目

题源链接
给定一个含有 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)) 时间复杂度的解法。


2 思路-滑动窗口

暴力解法的话当然是两个for循环,不断循环遍历寻找符合条件的子序列,时间复杂度很明显是O(n2)。这里不做阐述;

这里采用滑动窗口的思路。如果不太清晰的同学推荐大家去看Carl老师的视频讲解会更加清晰。
视频链接

什么是滑动窗口
就是不断的调节子序列的起始位置和终止位置,从而得出我们想要的结果。

在暴力解法中,是一个for循环滑动窗口的起始位置一个for循环为滑动窗口的终止位置,用两个for循环 完成了一个不断搜索区间的过程。

那么滑动窗口如何用一个for循环来完成这个操作呢。

首先要思考 如果用一个for循环,那么应该表示 滑动窗口的起始位置,还是终止位置。

如果只用一个for循环来表示 滑动窗口的起始位置,那么如何遍历剩下的终止位置?

此时难免再次陷入 暴力解法的怪圈。

所以 只用一个for循环,那么这个循环的索引,一定是表示 滑动窗口的终止位置

在本题中实现滑动窗口,主要确定如下三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。

窗口的起始位置如何移动: 如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

解题的关键在于 窗口的起始位置如何移动,如图所示:
在这里插入图片描述
可以发现滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。


3 代码


3.1 C版本

int minSubArrayLen(int target, int* nums, int numsSize){
    //初始化最小长度为INT_MAX
    int minLength = INT_MAX;
    int sum = 0;

    int left = 0, right = 0;
    //右边界向右扩展
    for(; right < numsSize; ++right) {
        sum += nums[right];
        //当sum的值大于等于target时,保存长度,并且收缩左边界
        while(sum >= target) {
            int subLength = right - left + 1;
            minLength = minLength < subLength ? minLength : subLength;
            sum -= nums[left++];
        }
    }
    //若minLength不为INT_MAX,则返回minLnegth
    return minLength == INT_MAX ? 0 : minLength;
}

3.2 C++版本

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX;
        int sum = 0;//滑动窗口内的和
        int i = 0;//滑动窗口的起始位置
        int WLength=0;//滑动窗口的大小
        for (int j = 0; j < nums.size(); j++) {//j代表滑动窗口的终止位置
            sum += nums[j];
            //使用while更新起始位置i,即尽量缩小窗口满足条件
            while (sum >= target) {
                WLength = j - i + 1;//取当前窗口的大小
                result = WLength < result ? WLength : result;
                sum -= nums[i++]; //滑动窗口精髓所在
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

3.3 Java版本

class Solution {

    // 滑动窗口
    public int minSubArrayLen(int s, int[] nums) {
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= s) {
                result = Math.min(result, right - left + 1);
                sum -= nums[left++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

3.4 JavaScript版本

var minSubArrayLen = function(target, nums) {
    let start, end
    start = end = 0
    let sum = 0
    let len = nums.length
    let ans = Infinity
    
    while(end < len){
        sum += nums[end];
        while (sum >= target) {
            ans = Math.min(ans, end - start + 1);
            sum -= nums[start];
            start++;
        }
        end++;
    }
    return ans === Infinity ? 0 : ans
};

4 总结

这道题做完对滑动窗口有了更加深入的理解。
key!!!就是如何从两个for遍历转换为一个for遍历,而一个for循环中,循环变量应该是滑动窗口的起始位置还是终止位置呢?
这些问题想清楚本题也就很好解决了。
非常感谢Carl老师。

相关题目推荐:
904.水果成篮
76.最小覆盖子串


By --Suki 2022/1/3
因为初试的时候可以说把数据结构和算法中的代码都牢牢的啃了一遍,在思考的过程中会很自然的就联想到一些经典排序算法的思想,例如归并排序,快排等等。这种感觉挺好的,基础很重要。一点一点由易到难吧。
你的努力不会白费。你思考过的每一步,都会为你今后的思想堡垒添砖加瓦。

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

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

相关文章

系列教程之《高铁上的GO》-第一篇

作者&#xff1a;坚果&#xff0c;OpenHarmony布道师&#xff0c;OpenHarmony校源行开源大使&#xff0c;CSDN博客专家&#xff0c;电子发烧友鸿蒙MVP&#xff0c;51CTO博客专家博主&#xff0c;阿里云博客专家。 本文主要讲解Go是什么&#xff0c;Go如何安装&#xff0c;开发G…

【Docker】(二)使用Dockerfile构建并发布一个SpringBoot服务

1.前言 在上一篇笔记 Docker基本概念与安装 中&#xff0c;我们已经获取到了一个Docker服务&#xff0c;并了解了Docker的基本组成及其各个组件的作用。 我们了解到&#xff0c;使用Docker的其中一个目的&#xff0c;是为了更加简单&#xff0c;方便的部署我们编写的服务&…

Typora下载和Markdown基础语法

本章内容如下&#xff1a; Typoar笔记下载资源及主题设置Markdown语法使用的基本方法 这篇博客一开始是为了教女朋友如何使用Typora和Markdown语法写的笔记&#xff0c;Markdown语法的内容不太全&#xff0c;只涉及基础使用。 文章目录Typora下载与主题设置Typora主题设置修改图…

在线考试答题系统的五大功能,你知道多少?

在线考试答题系统-五大功能&#xff0c;你知道多少&#xff1f;-在线考试答题系统优势&#xff1a;在线考试答题系统具有高度的可扩展性&#xff0c;高效灵活、功能强大。考试用户随时随地就可通过网络登录在线考试答题系统&#xff0c;参加在线报名、在线练习、在线考试、在线…

嵌入式开发中为什么选择C语言?它有哪些特点?

众所周知&#xff0c;C语言在嵌入式开发中占据着十分重要的地位&#xff0c;为什么嵌入式开发要选择C语言&#xff1f;嵌入式开发的方向可以分为单片机开发、Linx应用开发和现场可编辑逻辑门阵列&#xff08;FPGA)开发&#xff0c;不同于传统开发模式&#xff0c;操作系统是嵌入…

Nepnep x CatCTF Writeup

Web&#xff1a; 题目名称 ez_js 直接查看网页源代码&#xff0c;查看game.js&#xff0c;进入该目录即可得到flag Reverse&#xff1a; 题目名称 The cat did it 点进来看到一个看着很复杂的图像&#xff0c;离开的概率我猜是0% MD5加密&#xff0c;第一个即为flag Misc&am…

给在校学生的科普文:数字芯片后端工程师的日常

芯片后端设计&#xff0c;看似只是将网表中的晶体管摆放好。但并不是如同砖头砌墙那样简单粗暴。它是一门兼具形式美和工程实践需求的技术。形式美&#xff0c;直接来源于功能内容和需求&#xff0c;在后端设计的环节中&#xff0c;数以万计的标准单元如散乱的点点繁星&#xf…

2022年度穿戴设备行业分析:智能手表销额增长25%,智能手环销量下滑

当前&#xff0c;随着社会经济的发展与居民可支配收入的提高&#xff0c;居民的购买力逐渐增强&#xff0c;我国智能穿戴设备行业也得以快速发展。同时&#xff0c;随着相关技术的不断开发&#xff0c;我国智能穿戴设备行业的技术水平也持续提高。根据数据显示&#xff0c;智能…

软考中级数据库系统工程师好考吗?

数据库还好的&#xff0c;每年五月份考试&#xff0c;通过率20-30%。 数据库系统工程师&#xff0c;主要考核内容&#xff1a;数据库系统基本概念及关系理论&#xff1b;常用的大型数据库管理系统的应用技术&#xff1b;数据库应用系统的设计方法和开发过程&#xff1b;数据库系…

【C++修炼之路】12. stack queue类

每一个不曾起舞的日子都是对生命的辜负 stack&&queue一. stack的介绍和使用1. stack的介绍2. stack的使用二. stack的模拟实现三. queue的介绍和使用1. queue的介绍2. queue的使用四. queue的模拟实现五. deque的介绍和使用1. deque的介绍2. deque的使用3. deque的缺陷…

东方通无法加载程序jar包中的js

东方通中间件使用龙芯适配程序问题描述&#xff1a;东方通无法加载程序jar包中的js排查过程&#xff1a;根据以往经验确保东方通处于最新版本&#xff0c;确认版本为最新的检查容器配置&#xff0c;确认无误在东方通tongweb/bin/external.vmoption 里把-DWebModuleOnly参数值改…

Qt扫盲-QSS定制Qt Widget控件

QSS定制Qt Widget控件概述一、盒子模型二、子控件概述 在使用样式表时&#xff0c;每个部件都被视为具有四个同心矩形的盒子:外边距矩形、边界矩形、内边距矩形和内容矩形。 其实即是每一个继承至 QWidget 都支持的&#xff0c;这个和 前端的 CSS 里面的 盒子模型有些区别但是…

哪吒S亮相广州车展,定位B级燃油车颠覆者

2022年收官&#xff0c;哪吒汽车宣布全年交付152073台&#xff0c;其中&#xff1a; •哪吒U 51021台&#xff1b; •哪吒V 98847台&#xff1b; •哪吒S 2003台&#xff08;12月首月交付&#xff09;。与此同时&#xff0c;在年末的广州车展&#xff0c;哪吒汽车携全系车型参展…

Elastic-Job分布式任务调度(2):Elastic-Job快速入门

1 环境搭建 1.1 版本要求 JDK要求1.7及以上版本 Maven要求3.0.4及以上版本 zookeeper要求采用3.4.6及以上版本 1.2 Zookeeper安装&运行 自行查看我的zookeeper专题 ZooKeeper(3):ZooKeeper集群环境搭建_不死鸟.亚历山大.狼崽子的博客-CSDN博客 1.3 创建maven工程 创建…

Python代理IP的使用和代理池的设置

熟悉python的人都知道为了python的正常请求&#xff0c;维持数据的稳定获取&#xff0c;都会用到代理IP。代理IP不仅可以用来规避IP在单位时间的请求次数&#xff0c;还可以借助代理来隐藏真实的IP&#xff0c;避免出现“IP请求过于频繁”&#xff0c;“403”等报错。今天就带大…

甲方安全之仿真钓鱼演练(邮件+网站钓鱼)

文章目录一、简介1.1 前言1.2 整体思路1.3 演练所需1.4 各邮件厂商日群发上限二、钓鱼平台搭建及配置2.1 gophish平台搭建2.2 收件目标配置&#xff08;User & Groups&#xff09;2.3 发信邮箱配置&#xff08;Sending Profiles&#xff09;2.4 邮件模版配置&#xff08;Em…

Windows下socket网络编程,C++,Email的客户端程序(支持邮件基于SMTP的发送和POP3的接收)

阅读前请看一下&#xff1a;我是一个热衷于记录的人&#xff0c;每次写博客会反复研读&#xff0c;尽量不断提升博客质量。文章设置为仅粉丝可见&#xff0c;是因为写博客确实花了不少精力。不用担心你关注我而我却不关注你&#xff0c;因为我是个诚信互关的人&#xff01;&…

linux--管道

这里写自定义目录标题基本概念管道特征编写模型有名管道模型示例demowrite.cread.c结果无名管道基本概念 进程间存在天然的壁垒,进程间通信(Interperocess Communication,IPC)是指二个或者多个进程之间进行数据交换的过程 管道特征 管道是进程间通讯的一种常用方法。管道分为…

MyISAM 引擎和 InnoDB 引擎中索引存储的区别

一、MyISAM 引擎下的索引 MyISAM 存储引擎不支持行级锁&#xff0c;只有表级锁&#xff1b;不支持事务&#xff0c;也不支持外键&#xff0c;主要面向 OLAP 应用&#xff0c;是 MySQL 数据库5.5.8 版本之前默认的存储引擎&#xff0c;MyISAM 适用于不需要关心事务&#xff0c;…

实时即未来,大数据项目车联网之原始数据实时ETL任务HBase调优【九】

1. 原始数据实时ETL任务HBase调优 1.1 数据写入hbase优化 上一节写入数据,一条条数据put到表中,对于大量数据的写入,效率极低,因此针对此项进行优化 使用hbase客户端写缓存进行批量写入数据到hbase中 hbase客户端写缓存对象:BufferedMutator hbase的每一次put操作写入数据…