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. Java多态的向上转型和向下转型

    Java多态的向上转型和向下转型 向上转型:(子类转为父类,自动转型) 格式 :父类类型 变量名 = new 子类类型(); 注:子类赋值给父类,那这时这个父类就能调用子类的方法 向下转型:(父类转为 ...

  2. 解题8(FindLongestNumberStr)

    题目描述 样例输出 输出123058789,函数返回值9 输出54761,函数返回值5 接口说明 函数原型: unsignedint Continumax(char** pOutputstr,  ch ...

  3. Missing artifact org.hibernate:hibernate-core:jar:4.3.0.Final

    Missing artifact org.hibernate:hibernate-core:jar:4.3.0.Final

  4. javascript 表格排序和表头浮动效果(扩展SortTable)

    前段时间一个项目有大量页面用到表格排序和表头浮动的效果,在网上找了几个表格排序的js代码,最后选择了 Stuart Langridge的SortTable,在SortTable基础上做了些扩展,加上了 ...

  5. openvpn-admin(openvpn web管理 )

    openvpn 两种认证简介: 1.key分发: 在服务器端生成秘钥,然后下载到本地,将服务器端的ca.crt xx.crt xx.key ta.key(如果服务器启用的话需要,未开启的话不需要,功能 ...

  6. NumPy 迭代数组

    NumPy 迭代数组 NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式. 迭代器最基本的任务的可以完成对数组元素的访问. 接下来我们使用 arange() ...

  7. Python hash() 函数

    Python hash() 函数  Python 内置函数 描述 hash() 用于获取取一个对象(字符串或者数值等)的哈希值. 语法 hash 语法: hash(object) 参数说明: obje ...

  8. 如何成功再次安装MYSQL

    以前安过,后来再安装就是停在启动项就是过不去,无响应 弄了两天,期待奇迹,网上各种教程试了个遍就是不行,大体就是删除INI,清理注册表,以下是新的发现:(转载) 如果你的电脑里装过MySQL,想再重新 ...

  9. Python: packer方式加密js代码之解密函数

    起源: 解析一网站时,发现其视频信息为一段js代码动态生成,而此段js代码,是用packer加密的. 其加密后的代码段如下: eval(function(p,a,c,k,e,d){e=function ...

  10. 项目总结13:Jav文件压缩-InputStream转化为base64-Base64解码并生成图片

    Jav文件压缩-InputStream转化为base64-Base64解码并生成图片 直接上源码,解释见文章尾部 package com.hs.common.util.imgecode; import ...