题目:
思考:
- 我们要找到最短连续 子数组使得这个数组有序后整个nums有序
- 那么意味着 除了这个要找的数组以外的nums其余部分都已经有序
- 要使得这个数组长度最小,就要让这个数组前和数组后的原来的 有序部分最长
- 将nums分为三部分(nums1,nusm2,nums3)
- 可以知道nums1中最大的值要比nums2最小的值小(同理nums3最小的值要比nums2最大的值大)
- 利用这个性质得出nusm2的左右边界
- 从前往后遍历:维持一个最大值max_,遇到遍历值小于max_的时候说明这个值之前存在无序部分(也就是说这个值的位置pos是nums2的潜在右边界(为什么是潜在?因为要找最右边的无序位置)这样找到最右边的无序位置和最左的无序位置作为左右边界才能使得这个数组有序后整个nums有序)
- 从后往前遍历:同理不赘述
实现:
cpp
class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
int l=-1;
int r=-1;
int max_=INT_MIN;
int min_=INT_MAX;
for (int i=0;i<nums.size();i++)
{
if (nums[i]<max_)
{
l=i;
}
else
{
max_=nums[i];
}
}
for (int i=nums.size()-1;i>=0;--i)
{
if (nums[i]>min_)
{
r=i;
}
else
{
min_=nums[i];
}
}
return (l!=-1)?l-r+1:0;
}
};
合并遍历搜索:
cpp
class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
int l=-1;
int r=-1;
int max_=INT_MIN;
int min_=INT_MAX;
for (int i=0;i<nums.size();i++)
{
if (nums[i]<max_)
{
l=i;
}
else
{
max_=nums[i];
}
if (nums[nums.size()-i-1]>min_)
{
r=nums.size()-i-1;
}
else
{
min_=nums[nums.size()-i-1];
}
}
return (l!=-1)?l-r+1:0;
}
};