581. Shortest Unsorted Continuous Subarray
Brute Force(超时)
1 | class Solution { |
o(n^2) 每次遍历过程中,当nums[j] < nums[i]
,意味着2者都不在其正确位置,若要得到正确排序,需要进行位置的交换,但此处不要求交换,因此将i标记为Unsorted Array
的最底端,j标记为Unsorted Array
的最顶端
sort
1 | class Solution { |
O(nlogn)
排序后比较不同处的两个端点
stack
1 | class Solution { |
T(n):O(n) S(n):O(1)
1 | class Solution { |
T(n):O(n) S(n):O(1)
1 | class Solution { |
review
将数组分为三部分NumsA, NumsB, NumsC
其中NumsA和NumsC是有序的,而NumsB是无序的
他们具有如下的规律,NumsA中的所有数字小于NumsB中的最小数字,而NumsC中的所有数字都大于NumsB中的最大数字
转换条件就是NumsB和NumsC中的最小值大于NumsA中的最大值,NumsA和NumsB中的最大值小于NumsC中的最小值 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
int right = -1, left = -1;
int maxn = INT_MIN, minn = INT_MAX;
int n = nums.size();
// maxn记录NumsA和NumsB中的最大值,如果这个最大值比后面这个nums[i]大的话,说明不满足NumsA和NumsB中的最大值小于NumsC中的最小值
// 因此需要更新right为i,表示至少这个i是肯定不满足顺序的
// 如果都满足,就不断更新maxn为当前最大值,如果后面都是升序,那么right就不会变
// 因为需要获取左边部分的最大值,所以需要从左向右遍历
for(int i = 0; i < n; ++i)
{
if(maxn > nums[i])
right = i;
else
maxn = nums[i];
}
// minn记录NumsB和NumsC中的最小值,如果这个最小值比前面这个nums[i]小的话,说明不满足NumsB和NumsC中的最小值大于NumsA中的最大值
// 因此需要更新left为i,表示至少这个i是肯定不满足顺序的
// 如果都满足,就不断更新minn为当前最小值,如果后面都是降序,那么left就不会变
// 因为需要获取右边部分的最小值,所以需要从右向左遍历
for(int i = n - 1; i >= 0; --i)
{
if(minn < nums[i])
left = i;
else
minn = nums[i];
}
return right == -1 ? 0 : right - left + 1;
}
};