[LeetCode] Shortest Unsorted Continuous Subarray 最短无序连续子数组
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:
- Then length of the input array is in range [1, 10,000].
- 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/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Shortest Unsorted Continuous Subarray 最短无序连续子数组的更多相关文章
- Leetcode581.Shortest Unsorted Continuous Subarray最短无序连续子数组
给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: [2, 6, 4, 8, 1 ...
- LeetCode 581. 最短无序连续子数组(Shortest Unsorted Continuous Subarray)
581. 最短无序连续子数组 581. Shortest Unsorted Continuous Subarray 题目描述 给定一个整型数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序 ...
- LeetCode 581. Shortest Unsorted Continuous Subarray (最短无序连续子数组)
Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...
- Leetcode 581.最短无序连续子数组
最短无序连续子数组 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: [2, ...
- LeetCode Shortest Unsorted Continuous Subarray
原题链接在这里:https://leetcode.com/problems/shortest-unsorted-continuous-subarray/description/ 题目: Given a ...
- leetcode最短无序连续子数组
平民解法: 既然是找最小数组,那就得到一个排序好的数组,然后直接和初试数组比对,用一个left,right分别记录从最初开始不同,到最后不同的小标,最后左右做差再加一,就能得到长度. 其他解法: 双指 ...
- LeetCode 最短无序连续子数组
题目链接:https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/ 题目大意: 略. 分析: 如果排序区间为 [L ...
- 【leetcode_easy】581. Shortest Unsorted Continuous Subarray
problem 581. Shortest Unsorted Continuous Subarray 题意:感觉题意理解的不是非常明白. solution1: 使用一个辅助数组,新建一个跟原数组一模一 ...
- LeetCode算法题-Shortest Unsorted Continuous Subarray(Java实现)
这是悦乐书的第267次更新,第281篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第134题(顺位题号是581).给定一个整数数组,找到一个连续的子数组,按升序对该子数组 ...
随机推荐
- WEB页面异步调用场景测试
在我们测试异步调用前,我们首先弄清楚异步调用到底是什么? 异步调用的定义:一个可以无需等待被调用函数的返回值就让操作继续进行的方法, 举一个形象的例子就是:领导给A分配了一个任务, 然后领导就干其他事 ...
- 使用Java理解逻辑程序
1.Java常见的注释有哪些,语法是怎样的? 1)单行注释用//表示,编译器看到//会忽略该行//后的所文本 2)多行注释/* */表示,编译器看到/*时会搜索接下来的*/,忽略掉/* */之间的文本 ...
- 真是没想到,ikvm.net居然停止开发了。
看样子作者对.net已经失去了信心 http://weblog.ikvm.net/CommentView.aspx?guid=33ea525f-a291-418a-bd6a-abdf22d0662b# ...
- java 5并发中的阻塞队列ArrayBlockingQueue的使用以及案例实现
演示一个阻塞队列的使用 public class BlockingQueueTest { public static void main(String[] args) { //创建一个包含三个元素的阻 ...
- hackme.inndy.tw - pyyy - Writeup
hackme.inndy.tw - pyyy - Writeup 0x01 反编译 1.第一次尝试的时候我直接在线反编译,部分结果如下. for (i, f) in enumerate(F): n = ...
- 【iOS】swift init构造器
这几天在使用 Swift 重写原来的一个运动社交应用 SportJoin. 为什么要重写呢? 首先因为实在找不到设计师给我作图; 其次, 我也闲不下来, 想找一些项目做, 所以只好将原来的代码重写了. ...
- Autowired注解
package com.how2java.pojo; import org.springframework.beans.factory.annotation.Autowired; public cla ...
- JAVAEE——BOS物流项目09:业务受理需求分析、创建表、实现自动分单、数据表格编辑功能使用方法和工作单快速录入
1 学习计划 1.业务受理需求分析 n 业务通知单 n 工单 n 工作单 2.创建业务受理环节的数据表 n 业务通知单 n 工单 n 工作单 3.实现业务受理自动分单 n 在CRM服务端扩展方法根据手 ...
- PHP分页初探 一个最简单的PHP分页代码的简单实现
PHP分页代码在各种程序开发中都是必须要用到的,在网站开发中更是必选的一项. 要想写出分页代码,首先你要理解SQL查询语句:select * from goods limit 2,7.PHP分页代码核 ...
- Service Worker和HTTP缓存
很多人,包括我自己,初看Service Worker多一个Cache Storage的时候,就感觉跟HTTP长缓存没什么区别. 例如大家讲的最多的Service Worker能让网页离线使用,但熟悉H ...