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. Struts2学习笔记五 拦截器

    拦截器,在AOP中用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作.拦截是AOP的一种实现策略. Struts2中,拦截器是动态拦截Action调用的对象.它提供了一种机制可以使 ...

  2. 软件工程网络15团队作业1——团队组队&展示

    Deadline: 2018-3-25 10:00PM,以提交至班级博客时间为准. 申请开通团队博客,并将团队博客地址发表在本次随笔的评论中 团队展示 根据5-6人的组队要求,每个队伍创建团队博客并发 ...

  3. alpha-咸鱼冲刺day6-紫仪

    总汇链接 一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 !!!QAQ可以做到跟数据库交互了!!!!先来撒花花!(然后继续甲板) (然后就没有进展了.翻车+1s) 四,问题困难 ...

  4. MyGod_alpha版本测试报告

    买尬-Alpha版本测试报告 @(二手市场APP)[MyGod团队|团队项目|版本测试] 项目名称:武汉大学校园二手市场APP--买尬 软件版本:1.0.0 开发团队:MyGod 开发代表:程环宇 张 ...

  5. 简单的C语言编译器--语义制导翻译

      语法分析是最难写的,而这部分确实最伤脑的.大量的语义动作分析差点把我逼疯.   简而言之,这部分的作用就是在每次归约之后,都进行一些语义动作,最终让我们得到测试程序的三地址码,即中间代码. 1. ...

  6. zookeeper 启动失败 BindException: Address already in use 或者Error contacting service. It is probably not running

    平台:centos-6.3-i386 jdk-7u51 storm 0.9.1 python 2.6.6   hadoop 1.2.1 今天上午装storm的时候遇到这个问题,好郁闷.把网上介绍的方法 ...

  7. Win10下, TortoiseGit安装及配合Gitee使用完整版

    Windows10下, TortoiseGit的安装及使用, 并配合Gitee码云使用! 1) 安装TortoiseGit 官网, 32位, 64位, 自选 https://tortoisegit.o ...

  8. Python内置函数(53)——setattr

    英文文档: setattr(object, name, value) This is the counterpart of getattr(). The arguments are an object ...

  9. guava-19.0和google-collections-1.0 的 ImmutableSet 类冲突

    guava-19.0 google-collections-1.0 都有 ImmutableSet 类,包路径也一致,前者有 copyOf(Collection)? 一.应用报错: 二.解决办法 co ...

  10. 开发技巧(3-1)Eclipse查找关键字

    1.选择资源目录->选择search-file菜单 2.在弹出的对话框中, 输入要[搜索的字符串],选择[selected resources],点击[search]按钮 3.搜索结果