581. 最短无序连续子数组

581. 最短无序连续子数组

题目:

给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

请你找出符合题意的 最短 子数组,并输出它的长度。

示例:

示例 1:

输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。

示例 2:

输入:nums = [1,2,3,4]
输出:0

示例 3:

输入:nums = [1]
输出:0

提示:

  • 1 <= nums.length <= 104
  • -105 <= nums[i] <= 105

**进阶:**你可以设计一个时间复杂度为 O(n) 的解决方案吗?

解题:

方法一:排序比较

从示例1可以得知,数组可以分为三部分,nums1部分,nums2部分,nums3部分。当进行升序排序之后发现nums1部分和nums3部分不会发生变化,因此只要nums1+nums3部分求出最大,则可以得到nums2部分最短。

基本思路是:把原来的数组复制到另一个数组中进行排序,然后两个数组进行比较,然后我们从左向右找到第一个两数组不同的位置,即为 nums2 的左边界。同理也可以找到 nums2 的右边界。最后我们输出 nums2 的长度即可。

class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        if(is_sorted(nums.begin(),nums.end())) {
            // 如果数组已经是升序排序,返回0
            return 0;
        }
        vector<int> numsSorted(nums);
        sort(numsSorted.begin(), numsSorted.end());
        int left = 0;
        while(nums[left] == numsSorted[left]) {
            left++;
        }
        int right = nums.size()-1;
        while(nums[right] == numsSorted[right]) {
            right--;
        }
        return right-left+1;
    }
};

复杂度分析

  • 时间复杂度:O(nlog⁡n),其中 n 为给定数组的长度。我们需要 O(nlog⁡n) 的时间进行排序,以及 O(n) 的时间遍历数组,因此总时间复杂度为 O(n)。

  • 空间复杂度:O(n),其中 n 为给定数组的长度。我们需要额外的一个数组保存排序后的数组 numsSorted。

方法二:双指针一次遍历法

使用两个指针,一个从数组的开头向右移动,找到第一个无序的元素,另一个从数组的末尾向左移动,找到第一个无序的元素。然后,这两个指针之间的子数组就是我们要找的连续子数组。

class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        int n = nums.size();
        //从左向右找到第一个无序的元素
        int left = 0;
        while(left < n-1 && nums[left] <= nums[left+1]) {
            left++;
        }
        // 如果数组已经有序,返回0
        if(left == n-1) {
            return 0;
        }
        //从右向左找到第一个无序的元素
        int right = n-1;
        while(right > 0 && nums[right] >= nums[right - 1]) {
            right--;
        }
        //找到无序子数组的最小值和最大值
        int min_val = INT_MAX, max_val = INT_MIN;
        for(int i = left; i <= right; ++i) {
            min_val = min(min_val, nums[i]);
            max_val = max(max_val, nums[i]);
        }
        // 扩展左边界
        while(left > 0 && nums[left - 1] > min_val) {
            left--;
        }
        // 扩展右边界
        while(right < n-1 && nums[right + 1] < max_val) {
            right++;
        }
        // 返回子数组的长度
        return right - left + 1;
    }
};

更加简洁的写法:

class Solution {
public:
    int findUnsortedSubarray(std::vector<int>& nums) {
        int n = nums.size();
        int maxn = INT_MIN, right = -1;  // 初始化最大值和右边界
        int minn = INT_MAX, left = -1;   // 初始化最小值和左边界

        for (int i = 0; i < n; i++) {
            // 从左向右遍历找到右边界
            if (maxn > nums[i]) {
                right = i;
            } else {
                maxn = nums[i];
            }

            // 从右向左遍历找到左边界
            if (minn < nums[n - i - 1]) {
                left = n - i - 1;
            } else {
                minn = nums[n - i - 1];
            }
        }
        // 如果 right 仍然是初始值 -1,表示数组已经有序,返回 0
        // 否则,返回无序子数组的长度
        return right == -1 ? 0 : right - left + 1;
    }
};
int main() {
    std::vector<int> nums = {2, 6, 4, 8, 10, 9, 15};
    Solution solution;
    int result = solution.findUnsortedSubarray(nums);

    std::cout << "最短无序连续子数组的长度为: " << result << std::endl;

    return 0;
}

不理解?没关系,根据例子看图说话!

在这里插入图片描述
复杂度分析

  • 时间复杂度:O(n),其中 n 是给定数组的长度,我们仅需要遍历该数组一次。
  • 空间复杂度:O(1)。我们只需要常数的空间保存若干变量。

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

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

相关文章

【Android】声浪 UI 效果并附上详细代码

声浪效果是基于第三方实现的。 https://github.com/xfans/VoiceWaveView 将三方的 Kotlin 代码转 java 使用&#xff08;按照他的readme 进行依赖&#xff0c;好像少了点东西&#xff0c;至少本项目跑不起来&#xff09; 声浪效果在android 8 以上都是比较好的&#xff0c;不会…

【JavaEE】操作系统与进程

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

Oracle的控制文件多路复用,控制文件备份,控制文件手工恢复

一.配置控制文件多路复用 1.查询Oracle的控制文件所在位置 SQL> select name from v$controlfile;NAME -------------------------------------------------------------------------------- /u01/app/oracle/oradata/orcl/control01.ctl /u01/app/oracle/fast_recovery_a…

规划类3d全景线上云展馆帮助企业轻松拓展海外市场

科技3D线上云展馆作为一种基于VR虚拟现实和互联网技术的新一代展览平台。可以在线上虚拟空间中模拟真实的展馆&#xff0c;让观众无需亲自到场&#xff0c;即可获得沉浸式的参观体验。通过这个展馆&#xff0c;您可以充分、全面、立体展示您的产品、服务以及各种创意作品&#…

实用篇 | T-SNE可视化工具详情及代码示例

本文主要是为了快速的了解t-sne和如何快速使用&#xff01; 简要了解TSNE TSNE&#xff0c;降维方法之一。降维在机器学习中非常重要。这是因为如果使用高维数据创建模型&#xff0c;则很容易欠拟合。换句话说&#xff0c;有太多无用的数据需要学习。可以通过从各种数据中仅…

Golang版本处理Skywalking Trace上报数据

Tips: 中间记录了解决问题的过程&#xff0c;如不感兴趣可直接跳至结尾 首先去es里查询skywalking trace的元数据 可以拿到一串base64加密后的data_binary(直接解密不能用&#xff0c;会有乱码&#xff0c;可参考https://github.com/apache/skywalking/issues/7423) 对data_b…

第四代智能井盖传感器:智能井盖位移怎么进行监测

井盖是城市基础设施的一个重要组成部分&#xff0c;若井盖出现移位等现象&#xff0c;可能会对路过的车辆和行人造成潜在危险。特别是那些含有甲烷气体的井盖&#xff0c;一旦气体超过阈值且被意外踩踏&#xff0c;可能会导致气体的释放&#xff0c;这便会引发一系列安全事故&a…

Linux wait函数用法

wait 函数是用于等待子进程结束并获取子进程的终止状态的系统调用。它在父进程中使用&#xff0c;用于等待其子进程终止并获得子进程的退出状态。 函数原型&#xff1a; pid_t wait(int *status);status 是一个指向整型的指针&#xff0c;用于存储子进程终止时的退出状态&…

clang+llvm多进程gdb调试

clangllvm多进程gdb调试 前言1. 命令行gdb2. 父进程调试3. 子进程调试4. 返回父进程 前言 在学习新增llvm的优化pass时&#xff0c;需要跟踪clang及llvm的调用栈。然而llvm通过posix_spawn()创建了新进程&#xff0c;这使得gdb调试必须有一定的技巧了。 1. 命令行gdb 以下命…

小红书干货类笔记怎么写?建议收藏

小红书干货类笔记是指在小红书这个社交平台上&#xff0c;用户分享的各种实用、有价值的生活技巧、经验、心得等内容的笔记。这类笔记通常具有以下特点&#xff1a;内容详实、实用性强、独特见解、图文并茂。 比如&#xff1a;某个妆要怎么化、某种技能该怎么学、某个城市该怎…

详细梳理山姆·奥特曼离职闹剧 仍试图重返OpenAI

大家好,我是极智视界,欢迎关注我的公众号,获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码和资源下载,链接:https://t.zsxq.com/0aiNxERDq OpenAI 与微软围绕 Sam Altman 的离职风波,这场肥皂剧似乎还没到终结的样子。目前 …

跨越行业边界,CodeMeter护航AI领域安全与合规

在人工智能&#xff08;AI&#xff09;技术如ChatGPT的推动下&#xff0c;工业视觉、医疗诊断和智能驾驶等领域正在经历重大变革。这些技术不仅扩大了应用范围&#xff0c;也带来了数据安全、软件授权保护和合规性等新挑战。 AI工业视觉正在推动制造和自动化的快速发展&#x…

YOLOv5结合华为诺亚VanillaNet Block模块

🗝️YOLOv5实战宝典--星级指南:从入门到精通,您不可错过的技巧   -- 聚焦于YOLO的 最新版本, 对颈部网络改进、添加局部注意力、增加检测头部,实测涨点 💡 深入浅出YOLOv5:我的专业笔记与技术总结   -- YOLOv5轻松上手, 适用技术小白,文章代码齐全,仅需 …

出海企业首选的免费开源财务管理系统解决方案

计费与订阅管理 Odoo计费与订阅管理解决方案可帮助您同步从订单、计费到收入确认的复杂流程 Odoo Subscriptions将计费与订阅置于核心业务流程中&#xff0c;将其从普通的后端功能转化为具有决定性意义的战略性业务工具。Odoo统一计费框架支持根据事务、订阅、使用量计费以及…

大数据题目的解题技巧

目录 大数据题目的技巧总括 实例精析 实例一 实例二 实例三 大数据题目的技巧总括 &#xff08;1&#xff09;哈希函数可以把数据按照种类均匀分流&#xff1b; &#xff08;2&#xff09;布隆过滤器用于集合的建立与查询&#xff0c;并可以节省大量空间&#xff1b; &…

前缀和的动态维护——树状数组[C/C++]

文章目录 前言lowbitlowbit的定义lowbit的计算 树状数组的思想树状数组的操作单点修改 update前缀查询 query树状数组的建立 build 前言 树状数组巧妙了利用位运算和树形结构实现了允许单点修改的情况下&#xff0c;动态维护前缀和&#xff0c;并且实现单点修改和前缀和查询的效…

柱形图:制作图表时,有时会遇到柱形图系列没有居中显示,例如:

问题描述 制作图表时&#xff0c;有时会遇到柱形图系列没有居中显示&#xff0c;例如&#xff1a; 原因分析 柱形图的「分类」和「系列名」均选择了「地区」&#xff0c;导致分类下存在不同的系列&#xff0c;那么当前分类下没有的系列就会存在「空白占位」。 解决方案 此时…

多普勒流速仪的功能作用是什么?

我国地域广大&#xff0c;各地降雨分布不均&#xff0c;某些城市经常会出现连续的降雨进而导致城市排水压力过大&#xff0c;为了提高城市应对排水过量的极端情况的出现&#xff0c;亟需一种方案能够对城市排水进行有效及时的监测&#xff0c;从而能够及时的采取应对方案。 在污…

区域人员超限AI算法的介绍及TSINGSEE视频智能分析技术的行业应用

视频AI智能分析已经渗透到人类生活及社会发展的各个方面。从生活中的人脸识别、停车场的车牌识别、工厂园区的翻越围栏识别、入侵识别、工地的安全帽识别、车间流水线产品的品质缺陷AI检测等&#xff0c;AI智能分析技术无处不在。在某些场景中&#xff0c;重点区域的人数统计与…

详解Java的static关键字

文章目录 &#x1f384;静态方法&#x1f33a;静态方法和非静态方法对比&#x1f6f8;静态方法实例&#x1f6f8;非静态方法实例 &#x1f339;static关键字⭐static变量⭐static代码块 &#x1f384;静态方法 不依赖于对象实例&#xff1a;静态方法不需要依赖于任何对象实例&…