题目链接
解题思路:
从后往前遍历找到,不有序点,假设删除之前的所有元素
从前往后遍历,找到删除中间的序列,这里的序列都是子数组(必须是连续的),要注意一个问题就是会出现left指针大于right指针的情况,此时应该让right向后移动
left停下的位置,之前都是有序的,只要保证此时arr[left] <= arr[right]即可
要删除的中间区间为【left,right),size=right-left-1
注意不需要删除的情况和边界判断
class Solution{
public:
int findLengthOfShortestSubarray(vector<int> & arr){
int n=arr.size(),right=n-1;
while(right&&arr[right-1]<=arr[right])//从后向前遍历
--right;
if(right==0)return 0;//有序
int ans=right;//删除right个
for(int left=0;left==0||arr[left-1]<=arr[left];++left){//left之前有序
while(right<n&&arr[right]<arr[left])//right之后有序,并且arr[left] <= arr[right],保证删除之后序列依然有序
++right;
ans=min(ans,right-left-1);
}
return ans;
}
};
// #define arr a
// class Solution {
// public:
// int findLengthOfShortestSubarray(vector<int>& arr) {
// if(arr.size()==1)//一个元素肯定有序
// return 0;
// int n=arr.size();
// for(int i=0;i<n-1;i++)
// {
// if(a[i]>a[i+1])//遇到不是升序的,退出循环
// break;
// if(i+1==n-1)//走到最后都没有退出,序列有序,return 0;
// return 0;
// }
// return 0;
// }
// };
for(int left=0;left==0||arr[left-1]<=arr[left];++left)
这个for里的判断条件:left==0 || arr[left-1] <= arr[left]
让或操作,并让left == 0在前面这样就不会出现数组越界问题,因为left=0时,不会去判断后面的语句