每日一题:581.最短无序连续子数组
1、题目
给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
请你找出符合题意的 最短 子数组,并输出它的长度。
示例 1:
输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。
示例 2:
输入:nums = [1,2,3,4]
输出:0
示例 3:
输入:nums = [1]
输出:0
提示:
1 <= nums.length <= 104
-105 <= nums[i] <= 105
你可以设计一个时间复杂度为 O(n) 的解决方案吗?
2、解法
我们可以这么想,如果我们能够找到这个子数组的起始位置和终点位置,那么结果也就找到了。
起始位置:我们从右向左遍历,用minValue记录这个方向遇到的最小值,当遍历的当前位置大于这个最小值minValue时,说明子数组的起始位置至少在当前位置(有可能更往左,但绝对不会比当前位置更靠右,因为当前位置的值大于右侧某个值,所以这个子数组肯定是无序的)。ps:只要比右侧的最小值大,就说明不是升序的。
终点位置:我们从左向右遍历,用maxValue记录这个方向遇到的最大值,当遍历的当前位置小于这个最大值maxValue时,说明子数组的终点位置至少在当前位置。ps:只要比左侧的最大值小,就说明不是升序的。
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
length = len(nums)
if length == 0 or length == 1:
return 0
beginIndex = -1
minValue = nums[length-1]
for i in range(length-2, -1, -1):
if nums[i] > minValue:
beginIndex = i
else:
minValue = nums[i]
if beginIndex == -1: # 考虑[1,2,3,4]这种情况,说明整体已经是升序了
return 0
endIndex = 0
maxValue = nums[0]
for i in range(1, length):
if nums[i] < maxValue:
endIndex = i
else:
maxValue = nums[i]
return endIndex-beginIndex+1
执行用时:52 ms, 在所有 Python3 提交中击败了96.80%的用户
内存消耗:15.5 MB, 在所有 Python3 提交中击败了69.20%的用户