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 <=.

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的更多相关文章

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

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

  2. 【leetcode_easy】581. Shortest Unsorted Continuous Subarray

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

  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] Shortest Unsorted Continuous Subarray 最短无序连续子数组

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

  5. [Swift]LeetCode581. 最短无序连续子数组 | Shortest Unsorted Continuous Subarray

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

  6. Leeetcode--581. Shortest Unsorted Continuous Subarray

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

  7. 581. Shortest Unsorted Continuous Subarray

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

  8. 581. Shortest Unsorted Continuous Subarray连续数组中的递增异常情况

    [抄题]: Given an integer array, you need to find one continuous subarray that if you only sort this su ...

  9. LeetCode581. Shortest Unsorted Continuous Subarray

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

随机推荐

  1. 2.5、CDH 搭建Hadoop在安装(设置Cloudera Manager数据库)

    步骤5:设置Cloudera Manager数据库 Cloudera Manager Server包含一个可以为自己创建和配置数据库的脚本.该脚本可以: 创建Cloudera Manager Serv ...

  2. 如何搭建python+selenium2+eclipse的环境

    搭建python和selenium2的环境(windows) 1.下载并安装python(我用的是2.7的版本) 可以去python官网下载安装:http://www.python.org/getit ...

  3. 【Scheme】Huffman树

    (define (make-leaf symbol weight) (list 'leaf symbol weight)) (define (leaf? object) (eq? (car objec ...

  4. Android Studio 中的FindBugs插件使用,轻松帮你发现Bug (转)

    在日常开发过程中难免会因为一时疏忽而留下一些Bug,这些Bug就是埋在程序里的定时炸弹,如果不能及时铲除就会导致程序的不稳定,异常或闪退的现象,从而导致用户的体验的下降.那么怎么才能找出这些埋在程序里 ...

  5. pta l2-16(愿天下有情人都是失散多年的兄妹)

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805061769609216 题意:两个异性的人五服之内不得通婚 ...

  6. Floyd算法简介

    参考:https://blog.csdn.net/qq_35644234/article/details/60875818 一.Floyd算法的介绍    1.算法的特点:    弗洛伊德算法是解决任 ...

  7. Centos 7 下 LAMP 部署

    一.介绍 LAMP is a combination of operating system and open-source software stack. The acronym of LAMP i ...

  8. HDU-1459.非常可乐(BFS )

    这道题TLE了很多次,原来一直以为将数字化为最简可以让运算更快,但是去了简化之后才发现,真正耗时的就是化简....还和队友学到了用状态少直接数组模拟刚就能过... 本题大意:给出可乐的体积v1,给出两 ...

  9. 100. Same Tree (Tree;DFS)

    Given two binary trees, write a function to check if they are equal or not. Two binary trees are con ...

  10. 模拟点击事件在alert前不起作用

    本来想在ajax提交前点击一下模态框,直到返回处理之前都显示正在保存,发现如标题的现象,几经折腾没找到解决办法,发现可能是 alert线程阻塞(冒泡)引起的,也没找到解决办法,于是借助第三方插件lay ...