Shortest Unsorted Continuous Subarray LT581
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 <=.
Idea 1. Similar to Max Chunks To Make Sorted II LT768, find the chunks and merge chunks by updating the end index, start index is the staring point of first chunk, the lengh = end index - start index.
The key point is: The array is considered sorted if the left elements are smaller or equal than the right elements, that is, the maximum of the left subarray is smaller or equal than the minimum of the right subarray.
The unsorted chunks can be found by:
a. store the minValue from right to left
b. stack in ascending order.
Time complexity: O(n)
Space complexity: O(n)
1.a
class Solution {
public int findUnsortedSubarray(int[] nums) {
int sz = nums.length;
int[] rightMin = new int[sz];
rightMin[sz-1] = nums[sz-1];
for(int i = sz-2; i >= 0; --i) {
rightMin[i] = Math.min(rightMin[i+1], nums[i]);
}
int startIndex = -1;
int endIndex = -1;
int currMax = Integer.MIN_VALUE;
for(int i = 0; i + 1 < sz; ++i) {
currMax = Math.max(currMax, nums[i]);
if(currMax > rightMin[i+1]) {
if(startIndex == -1) {
startIndex = i; // first unsorted chunk
}
else {
endIndex = -1; // new unsorted chunk, mark endIndex = -1 to merge
}
}
else if(startIndex != -1 && endIndex == -1){
endIndex = i; // if curMax <= rightMin[i+1], means nums(i+1...end) is sorted
}
}
if(startIndex == -1) {
return 0;
}
if(endIndex == -1) {
endIndex = sz - 1;
}
return endIndex - startIndex + 1;
}
}
1.b stack
class Solution {
public int findUnsortedSubarray(int[] nums) {
Deque<Integer> ascendingStack = new LinkedList<>();
int startIndex = nums.length;
int endIndex = -1;
int currMaxIndex = 0;
for(int i = 0; i < nums.length; ++i) {
if(currMaxIndex == nums.length || nums[currMaxIndex] < nums[i] ) {
currMaxIndex = i;
}
while(!ascendingStack.isEmpty() && nums[ascendingStack.peek()] > nums[i]) {
startIndex = Math.min(startIndex, ascendingStack.pop()); // unsorted chunk
endIndex = -1;
}
ascendingStack.push(currMaxIndex);
if(startIndex != nums.length && endIndex == -1) {
endIndex = i; // the end of unsorted chunk: the current index i
}
}
if(startIndex == nums.length) {
return 0; // the array is sorted
}
return endIndex - startIndex + 1;
}
}
Idea 2. The boundary of unsorted subarray is determined by the leftmost and rightmost elements not in the correct position(the sorted position). Borrow the idea from selection sort, for any pair of integeras (0 < i < j < nums.length), if num[i] > nums[j], this pair will get swapped to get the right position for the sorted array, since we only require the bounday, there is no need to sort it, just note down the index of elements which mark the boundary of the unsorted subarray. Hence, out of all pairs, the leftmost index i not at it's correct position is the left boundary, the rightmost index j is the right boundary.
Time complexity: O(n2)
Space complexity: O(1)
class Solution {
public int findUnsortedSubarray(int[] nums) {
int startIndex = nums.length;
int endIndex = -1;
for(int i = 0; i < nums.length; ++i) {
for(int j = i; j < nums.length; ++j) {
if(nums[i] > nums[j]) {
startIndex = Math.min(startIndex, i);
endIndex = Math.max(endIndex, j);
}
}
}
if(startIndex == nums.length) {
return 0;
}
return endIndex - startIndex + 1;
}
}
Idea 3. Comparing with the correct position in the sorted array, mark down the leftmost index and rightmost index different from the sorted position.
Time complexity: O(nlogn)
Space complexity: O(n)
class Solution {
public int findUnsortedSubarray(int[] nums) {
int[] numsSorted = Arrays.copyOf(nums, nums.length);
Arrays.sort(numsSorted);
int startIndex = nums.length;
int endIndex = -1;
for(int i = 0; i < nums.length; ++i) {
if(nums[i] != numsSorted[i]) {
startIndex = Math.min(startIndex, i);
endIndex = Math.max(endIndex, i);
}
}
if(startIndex == nums.length) {
return 0;
}
return endIndex - startIndex + 1;
}
}
Idea 4. The correct position of the minimum element in the unsorted subarray determins the left boundary, the correct position of the maximum element in the unsorted subarray determins the right boundary. Two steps: 1. Find the unsorted subarray 2. find the minimum and maximum
a. stack in ascending order for min, in descending order for maxmum
While traversing over the nums array starting from the begining, pushing elements over the stack if in asecending order, otherwise in a falling slope(unsorted subarray), an element nums[j] smaller than the element on the top of the stack, poping elements in the stack until the elemnts on the top is equal or smaller than nums[j], the last poped element is the correct position for nums[j]. For all the nums[j] not in correct position, the minmum of the correct positions determins the left boundary.
Time complexity: O(n)
Space complexity: O(n)
class Solution {
public int findUnsortedSubarray(int[] nums) {
Deque<Integer> indexStack = new LinkedList<>();
int startIndex = nums.length;
int endIndex = -1;
for(int i = 0; i < nums.length; ++i) {
while(!indexStack.isEmpty() && nums[indexStack.peek()] > nums[i]) {
startIndex = Math.min(startIndex, indexStack.pop());
}
indexStack.push(i);
}
for(int i = nums.length-1; i >= 0; --i) {
while(!indexStack.isEmpty() && nums[i] > nums[indexStack.peek()]) {
endIndex = Math.max(endIndex, indexStack.pop());
}
indexStack.push(i);
}
if(startIndex == nums.length) {
return 0;
}
return endIndex - startIndex + 1;
}
}
b. without extra space, rising slope starting from the begining, falling slope staring from the end
Time complexity: O(n)
Space complexity: O(1)
C1 class Solution {
public int findUnsortedSubarray(int[] nums) {
int startIndex = 0;
while(startIndex+1 < nums.length && nums[startIndex] <= nums[startIndex+1]) {
++startIndex;
}
if(startIndex == nums.length-1) {
return 0;
}
int minItem = nums[startIndex+1];
for(int i = startIndex+1; i < nums.length; ++i) {
minItem = Math.min(minItem, nums[i]);
}
// nums[0..startIndex] is sorted,
// the correct position is the index of the first element bigger than minItem
// from 0 to startIndex (left to right)
for(int i = 0; i <= startIndex; ++i) {
if(nums[i] > minItem) {
startIndex = i;
break;
}
}
int endIndex = nums.length-1;
while(endIndex-1 >= 0 && nums[endIndex-1] <= nums[endIndex]) {
--endIndex;
}
int maxItem = nums[endIndex-1];
for(int i = endIndex-1; i >= 0; --i) {
maxItem = Math.max(maxItem, nums[i]);
}
// nums[endIndex, nums.length-1] is sorted
// the correct position of the index of the first element smaller than maxItem
// from nums.length-1 to endIndex (right to left)
for(int i = nums.length-1; i>= endIndex; --i) {
if(nums[i] < maxItem) {
endIndex = i;
break;
}
}
return endIndex - startIndex + 1;
}
}
Find the first unsorted subarray and the minimum element can be combine in one loop to make code more concise.
class Solution {
public int findUnsortedSubarray(int[] nums) {
int minItem = Integer.MAX_VALUE;
boolean isSorted = true;
for(int i = 1; i < nums.length; ++i){
if(nums[i-1] > nums[i]) {
isSorted = false;
}
if(!isSorted) {
minItem = Math.min(minItem, nums[i]);
}
}
if(isSorted) {
return 0;
}
int startIndex = 0;
for(; startIndex < nums.length; ++startIndex) {
if(nums[startIndex] > minItem) {
break;
}
}
int maxItem = Integer.MIN_VALUE;
isSorted = true;
for(int i = nums.length-2; i >= 0; --i) {
if(nums[i] > nums[i+1]) {
isSorted = false;
}
if(!isSorted) {
maxItem = Math.max(maxItem, nums[i]);
}
}
int endIndex = nums.length-1;
for(;endIndex >= 0; --endIndex) {
if(nums[endIndex] < maxItem) {
break;
}
}
return endIndex - startIndex + 1;
}
}
Shortest Unsorted Continuous Subarray LT581的更多相关文章
- LeetCode 581. 最短无序连续子数组(Shortest Unsorted Continuous Subarray)
581. 最短无序连续子数组 581. Shortest Unsorted Continuous Subarray 题目描述 给定一个整型数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序 ...
- 【leetcode_easy】581. Shortest Unsorted Continuous Subarray
problem 581. Shortest Unsorted Continuous Subarray 题意:感觉题意理解的不是非常明白. solution1: 使用一个辅助数组,新建一个跟原数组一模一 ...
- 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] Shortest Unsorted Continuous Subarray 最短无序连续子数组
Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...
- [Swift]LeetCode581. 最短无序连续子数组 | Shortest Unsorted Continuous Subarray
Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...
- Leeetcode--581. Shortest Unsorted Continuous Subarray
Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...
- 581. Shortest Unsorted Continuous Subarray
Given an integer array, you need to find one continuous subarray that if you only sort this subarr ...
- 581. Shortest Unsorted Continuous Subarray连续数组中的递增异常情况
[抄题]: Given an integer array, you need to find one continuous subarray that if you only sort this su ...
- LeetCode581. Shortest Unsorted Continuous Subarray
Description Given an integer array, you need to find one continuous subarray that if you only sort t ...
随机推荐
- 1.3.1、CDH 搭建Hadoop在安装之前(端口---Cloudera Manager和Cloudera Navigator使用的端口)
下图概述了Cloudera Manager,Cloudera Navigator和Cloudera Management Service角色使用的一些端口: Cloudera Manager和Clou ...
- Java中的IO流,Input和Output的用法,字节流和字符流的区别
Java中的IO流:就是内存与设备之间的输入和输出操作就成为IO操作,也就是IO流.内存中的数据持久化到设备上-------->输出(Output).把 硬盘上的数据读取到内存中,这种操作 成为 ...
- 使用ddns搭建免费服务器
[使用ddns搭建免费服务器] 第一步 tplink路由器提供了ddns服务,它为用户免费提供一个子tpddns.cn下的子域名,映射到你的路由器上.当启用后,只在要能接入互联网的地方,都能过此域名, ...
- Mybatis多个in查询
Map<String, Object> params = null; List<Map<String, Object>> list=new ArrayList(); ...
- Python之 ---成员修饰符
一:成员修饰符:分为共有成员和私有成员: 私有成员:__通过两个下滑线:无法直接访问,要访问只能间接访问: 如下我们定义了一个对象,里面有两个共有的成员变量,成员变量是共有的时候我们可以外部访问,如果 ...
- 下载excel
使用struts2的方式完成下载 对于下载excel2003,contentType如此设置 <result name="success" type="stream ...
- BufferedReader .BufferedWriter执行文本复制
/** * 需求:演示 BufferedReader 和 BufferedWriter 的使用,复制一个 java 文件 */ package cn.itcast.others.iostream; i ...
- 牛客网练习赛43-C(图论)
题目链接:https://ac.nowcoder.com/acm/contest/548/C 题意:有n个知识点,学会每个知识点花T[i],已经学会了其中k个知识点,有m组关系,t1,t2,t3,表示 ...
- 与服务器同步工程(expect脚本)
先看下我实际用的例子: #!/usr/bin/expect spawn rsync -vazu ssh-src/src wayne@192.168.5.2:~/projects/ expect &qu ...
- FPGA功耗那些事儿(转载)
在项目设计初期,基于硬件电源模块的设计考虑,对FPGA设计中的功耗估计是必不可少的.笔者经历过一个项目,整个系统的功耗达到了100w,而单片FPGA的功耗估计得到为20w左右,有点过高了,功耗过高则会 ...