Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too.

You need to find the shortest such subarray and output its length.

Example 1:

Input: [2, 6, 4, 8, 10, 9, 15]
Output: 5
Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order.

Note:

  1. Then length of the input array is in range [1, 10,000].
  2. The input array may contain duplicates, so ascending order here means <=.

这道题给了我们一个数组,让我们求最短的无序连续子数组,根据题目中的例子也不难分析出来是让我们找出数组中的无序的部分。那么我最开始的想法就是要确定无序子数组的起始和结束位置,这样就能知道子数组的长度了。所以我们用一个变量start来记录起始位置,然后我们开始遍历数组,当我们发现某个数字比其前面的数字要小的时候,说明此时数组不再有序,所以我们要将此数字向前移动,移到其应该在的地方,我们用另一个变量j来记录移动到的位置,然后我们考虑要不要用这个位置来更新start的值,当start还是初始值-1时,肯定要更新,因为这是出现的第一个无序的地方,还有就是如果当前位置小于start也要更新,这说明此时的无序数组比之前的更长了。我们举个例子来说明,比如数组[1,3,5,4,2],第一个无序的地方是数字4,它移动到的正确位置是坐标2,此时start更新为2,然后下一个无序的地方是数字2,它的正确位置是坐标1,所以此时start应更新为1,这样每次用i - start + 1来更新结果res时才能得到正确的结果,参见代码如下:

解法一:

class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
int res = , start = -, n = nums.size();
for (int i = ; i < n; ++i) {
if (nums[i] < nums[i - ]) {
int j = i;
while (j > && nums[j] < nums[j - ]) {
swap(nums[j], nums[j - ]);
--j;
}
if (start == - || start > j) start = j;
res = i - start + ;
}
}
return res;
}
};

下面这种方法是用了一个辅助数组,我们新一个跟原数组一摸一样的数组,然后排序。从数组起始位置开始,两个数组相互比较,当对应位置数字不同的时候停止,同理再从末尾开始,对应位置上比较,也是遇到不同的数字时停止,这样中间一段就是最短无序连续子数组了,参见代码如下:

解法二:

class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
int n = nums.size(), i = , j = n - ;
vector<int> t = nums;
sort(t.begin(), t.end());
while (i < n && nums[i] == t[i]) ++i;
while (j > i && nums[j] == t[j]) --j;
return j - i + ;
}
};

下面这种方法很叼啊,是O(n)的时间复杂度加上O(1)的空间复杂度,博主觉得这实际上是对上面的那种方法进行空间上的优化的结果,用两个变量mx和mn来代替上面的有序数组,我们仔细来分析发现,最小值mn初始化为数组的最后一个数字,最大值mx初始化为了第一个数字,然后我们从第二个数字开始遍历,mx和nums[i]之间取较大值赋值给mx,然后比较此时mx和nums[i]之间的大小关系,如果mx大于nums[i],就把i赋值给end,那么我们想如果第一个数字小于第二个,mx就会赋值为第二个数字,这时候mx和nums[i]就相等了,不进行任何操作,这make sense,因为说明此时是有序的。mn和nums[n-1-i]之间取较小值赋给mn,然后比较此时mn和nums[n-1-i]之间的大小关系,如果mn小于nums[n-1-i],就把n-1-i赋值给start,那么什么时候会进行赋值呢,是当倒数第二个数字大于最后一个数字,这样mn还是最后一个数字,而nums[n-1-i]就会大于mn,这样我们更新start。我们可以看出start是不断往前走的,end是不断往后走的,整个遍历完成后,start和end就分别指向了最短无序连续子数组的起始和结束位置,参见代码如下:

解法三:

class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
int n = nums.size(), start = -, end = -;
int mn = nums[n - ], mx = nums[];
for (int i = ; i < n; ++i) {
mx = max(mx, nums[i]);
mn = min(mn, nums[n - - i]);
if (mx > nums[i]) end = i;
if (mn < nums[n - - i]) start = n - - i;
}
return end - start + ;
}
};

参考资料:

https://leetcode.com/problems/shortest-unsorted-continuous-subarray/

https://leetcode.com/problems/shortest-unsorted-continuous-subarray/discuss/103057/java-on-time-o1-space

https://leetcode.com/problems/shortest-unsorted-continuous-subarray/discuss/103062/c-clean-code-2-solution-sort-onlgn-max-min-vectors-on

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Shortest Unsorted Continuous Subarray 最短无序连续子数组的更多相关文章

  1. Leetcode581.Shortest Unsorted Continuous Subarray最短无序连续子数组

    给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: [2, 6, 4, 8, 1 ...

  2. LeetCode 581. 最短无序连续子数组(Shortest Unsorted Continuous Subarray)

    581. 最短无序连续子数组 581. Shortest Unsorted Continuous Subarray 题目描述 给定一个整型数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序 ...

  3. LeetCode 581. Shortest Unsorted Continuous Subarray (最短无序连续子数组)

    Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...

  4. Leetcode 581.最短无序连续子数组

    最短无序连续子数组 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: [2, ...

  5. LeetCode Shortest Unsorted Continuous Subarray

    原题链接在这里:https://leetcode.com/problems/shortest-unsorted-continuous-subarray/description/ 题目: Given a ...

  6. leetcode最短无序连续子数组

    平民解法: 既然是找最小数组,那就得到一个排序好的数组,然后直接和初试数组比对,用一个left,right分别记录从最初开始不同,到最后不同的小标,最后左右做差再加一,就能得到长度. 其他解法: 双指 ...

  7. LeetCode 最短无序连续子数组

    题目链接:https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/ 题目大意: 略. 分析: 如果排序区间为 [L ...

  8. 【leetcode_easy】581. Shortest Unsorted Continuous Subarray

    problem 581. Shortest Unsorted Continuous Subarray 题意:感觉题意理解的不是非常明白. solution1: 使用一个辅助数组,新建一个跟原数组一模一 ...

  9. LeetCode算法题-Shortest Unsorted Continuous Subarray(Java实现)

    这是悦乐书的第267次更新,第281篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第134题(顺位题号是581).给定一个整数数组,找到一个连续的子数组,按升序对该子数组 ...

随机推荐

  1. 深入理解Android中View

    文章目录   [隐藏] 一.View是什么? 二.View创建的一个概述: 三.View的标志(Flag)系统 四.MeasureSpec 五.几个重要方法简介 5.1 onFinishInflate ...

  2. lua对多个精灵执行一系列动作,延时失效

    function MainPlayerCards:sendCards() local winSize = cc.Director:getInstance():getWinSize() local nS ...

  3. 在Python中使用Redis

    在Python中要使用Redis数据库,首先要安装redis 之前的博客中有写到在命令行模式下操作Redis数据库. 要在项目中使用的话可以这么做: 通过初始化 redis.Redis,得到返回的对象 ...

  4. apache学习教程

    5.apache教程 httpd.conf文件分析 ServerRoot "E:/phpwebenv/PHPTutorial/Apache" #apache软件安装的位置 List ...

  5. Beta 第一天

    一.今日任务 重新熟悉整体项目 对整个项目在未来的beta冲刺中进程有一个合理的规划 由于我们送出的是一个负责前端的成员,引入的也是一个负责前端工作的女生,(女生做起美工比起男生更加得心应手吧)所以我 ...

  6. C语言数据类型作业

    一.PTA实验作业 题目1:7-4 打印菱形图案 1. 本题PTA提交列表 2. 设计思路 1.定义m,n(用于计算空格数,输出"* "数),i,j,k(用于循环) 2.输入n,并 ...

  7. js日常积累

    1.数组转字符串 str.join(',') 2.字符串转数组 arr.split(',') 3.数组排序 function sorb(a,b){return a-b;}; arr.sort(sorb ...

  8. 从Nest到Nesk -- 模块化Node框架的实践

    文: 达孚(沪江Web前端架构师) 本文原创,转至沪江技术 首先上一下项目地址(:>): Nest:https://github.com/nestjs/nest Nesk:https://git ...

  9. OO第一次阶段性总结

    经过三次作业的历练之后终于来到了写博客这一周.回顾开学来的这一个月,令我印象最深刻也是最累的一门课就是OO了.虽然上学期学过一部分Java,但这学期开学就来的OO作业还是让我在第二周就开始熬夜了.不过 ...

  10. LeetCode & Q35-Search Insert Position-Easy

    Array Binary Search Description: Given a sorted array and a target value, return the index if the ta ...