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. 关于使用Unity开发Kinect时出现的Runtime Error错误的解决方式

    一.开发环境: 1. 硬件:Kinect 2.0 2. 操作系统:Windows10 3. Unity版本:5.x以上 4. Kinect SDK:KinectSDK-v2.0_1409 5. Kin ...

  2. KS检验统计量的扩展应用(CMap)

    KS检验统计量的扩展应用 KS(Kolmogorov-Smirnov)检验是比较两个经验分布之间是否存在差异. 我们设X1, X2,-, Xm, Y1, Y2,-, Ym为两个独立随机样本,分别满足假 ...

  3. 和sin有关的代码

    include include using namespace std; const double TINY_VALUE=1e-10; double tsin(double x) { double g ...

  4. Idea简单SpringMVC框架配置

    前边已经介绍过了Struts在Idea上的配置,相对于Struts来说,我觉得SpringMVC有更多的优势,首先Struts是需要对action进行配置,页面发送不同的请求,就需要配置不同的acti ...

  5. 第二次作业:软件分析之Steam的前世今生

    摘要:本次作业我将介绍一下Steam的相关内容,以及对Steam的相关调研测评,以及需求分析,最后就是对Steam的建议以及在中国的发展提出相应的建议 一.相关信息      Steam是一个整合游戏 ...

  6. C语言第八次作业

    一.PTA实验作业 题目1:统计一行文本的单词个数 1.本题PTA提交列表 2.设计思路 // 一个非空格和一个空格代表一个单词 char str[1000]: 存放一行文本 定义 I,j=0:用作循 ...

  7. C语言程序设计第四次作业——选择结构(2)

    Deadline: 2017-11-5 22:00 一.学习要点 掌握switch语句 掌握字符常量.字符串常量和字符变量 掌握字符型数据的输入输出 二.实验内容 完成PTA中选择结构(2)的所有题目 ...

  8. 201621123057 《Java程序设计》第2周学习总结

    一.本周学习总结 基本数据类型 char实质属于整型.boolean类型取值只有true和false两种. 引用数据类型 包装类:自动装箱 与 自动拆箱 数组:一维数组遍历数组用foreach循环:多 ...

  9. Scrum 冲刺 第二日

    Scrum 冲刺 第二日 目录 要求 项目链接 燃尽图 问题 今日任务 明日计划 成员贡献量 要求 各个成员今日完成的任务(如果完成的任务为开发或测试任务,需给出对应的Github代码签入记录截图:如 ...

  10. Flask 扩展 Flask-RESTful

    Flask路由可以指定HTTP请求方法,并在请求函数中根据不同的请求方法,执行不同的逻辑.这样实现一个Restful的请求已经相当简单了 Flask还有更简便的方法,就是其Flask-RESTful扩 ...