581. 最短无序连续子数组(Shortest Unsorted Continuous Subarray)
题解
两次遍历
第一次简历:
从前向后遍历,使用
m
a
x
_
n
u
m
max\_num
max_num,保存到当前位置为止的最大值,若下个数大于等于
m
a
x
_
n
u
m
max\_num
max_num,则更新
m
a
x
_
n
u
m
max\_num
max_num。否则,更新需要排序数组的右界
r
i
g
h
t
right
right。
- 初始化 r i g h t = 0 right=0 right=0, m a x _ n u m = n u m s [ 0 ] max\_num=nums[0] max_num=nums[0]
- 遍历数组,遍历区间
[
0
,
n
)
[0,n)
[0,n):
- 若 n u m s [ i ] > = m a x _ n u m nums[i]>=max\_num nums[i]>=max_num,更新 m a x _ n u m = n u m s [ i ] max\_num=nums[i] max_num=nums[i]
- 否则,更新右界 r i g h t = i right=i right=i
第二次简历:
从后向前遍历,使用
m
i
n
_
n
u
m
min\_num
min_num,保存到当前位置为止的最小值,若下个数小于等于
m
i
n
_
n
u
m
min\_num
min_num,则更新
m
i
n
_
n
u
m
min\_num
min_num。否则,更新需要排序数组的左界
l
e
f
t
left
left。
- 初始化 l e f t = n left=n left=n, m i n _ n u m = n u m s [ − 1 ] min\_num=nums[-1] min_num=nums[−1]
- 遍历数组,遍历区间
(
n
,
0
]
(n,0]
(n,0]:
- 若 n u m s [ i ] < = m i n _ n u m nums[i]<=min\_num nums[i]<=min_num,更新 m i n _ n u m = n u m s [ i ] min\_num=nums[i] min_num=nums[i]
- 否则,更新左界 r i g h t = i right=i right=i
若 r i g h t − l e f t + 1 > 0 right-left+1>0 right−left+1>0,返回 r i g h t − l e f t + 1 right-left+1 right−left+1,否则,返回 0 0 0
复杂度分析
- 时间复杂度: O ( n ) O\left(n\right) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
Python
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
n=len(nums)
max_num=nums[0]
right=0
for i in range(n):
if(nums[i]>=max_num):
max_num=nums[i]
else:
right=i
left=n
min_num=nums[-1]
for i in range(n-1,-1,-1):
if(nums[i]<=min_num):
min_num=nums[i]
else:
left=i
return right-left+1 if(right-left+1 >0) else 0
Java(待完成)
排序比对
很自然的想法,将原数组copy并排序,和原数组比对。
复杂度分析
- 时间复杂度: O ( n l o g ( n ) ) O\left(nlog(n)\right) O(nlog(n))
- 空间复杂度: O ( n ) O(n) O(n)
Python
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
nums_copy=nums[:]
nums_copy.sort()
left=float("inf")
right=0
for i in range(len(nums)):
if(nums_copy[i]!=nums[i]):
left=min(left,i)
right=max(right,i)
return right-left+1 if(right-left+1 > 0) else 0