"""
https://leetcode.cn/problems/shortest-subarray-to-be-removed-to-make-array-sorted/
题目分析:
这题是中等难度题,本来以为是划动窗体,参考题解用了双指针
分两大部分:
先是右指针向左移动,获取右侧有序字符串
后面是左、右指针同时移动,获取最小子字符串subStr
理论:双指针
1.先用右指针>right,从右到左,一直到递减数组结束
2.此时,如果righ==0,表示整个数组是有序数组;直接返回0
3.此时,right<>0表示有非有序存在
4.用左指针>left,从左到右循环有序
5.右指针同时向右移动,,直到左、右指针的值满足有序
6.计算需要删除数组大小subStr=arr[left+1:right];
7.保存最小需要删除值ret=min(ret,subStr)
8.返回结果ret
注意/难点:
边界处理
"""
class Solution:
def findLengthOfShortestSubarray(self, arr:list) -> int:
n=len(arr) #数组长度
right=n-1 #右指针
while right>0 and arr[right-1]<=arr[right]: #从右到左判断有序数组
right-=1
if right==0:return 0 #原数组是有序数组
#这时arr[right-1]>arr[right]
ret=right #初始化结果ret,表示移除前面部分arr[:right]
left=0 #左指针
while left==0 or arr[left-1]<=arr[left]: #不要忘了left=0的情况
while right<n and arr[right]<arr[left]: #右指针后移
right+=1
#这时指针的值arr[left]<arr[right],删除arr[left+1:right]
print(arr[left+1:right])
subStr=right-left-1 #计算删除字符串长度
ret=min(subStr,ret) #取较小值
left+=1 #左指针后移
return ret
arr = [1,2,3,3,10,1,3,3,5]
ans=Solution().findLengthOfShortestSubarray(arr)
print(ans)
左、右指针变化如下
以下数据展示双指针索引以及区间变化 | ||||||||||||
idx-> | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ret | ||
arr-> | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | |||
while right>0 and arr[right-1]<=arr[right]: | ||||||||||||
right=(n-1)=8 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | |||
right-1=7 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | |||
right-1=6 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | |||
right-1=5 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | ret=[:right]=[1,2,3,3,10]=5 | ||
while left==0 or arr[left-1]<=arr[left]: | ||||||||||||
while right<n and arr[right]<arr[left]: | ||||||||||||
left=0;right=5 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | ret=[left+1:right]=[2,3,3,10]=4 | ||
left=1;right=5 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | right<left,right+1 | ||
left=1;right=6 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | ret=[left+1:right]=[3,3,10,1]=4 | ||
left=2;right=6 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | ret=[left+1:right]=[3,10,1]=3 | ||
left=3;right=6 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | ret=[left+1:right]=[10,1]=2 | ||
left=4;right=6 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | right<left,right+1 | ||
left=4;right=7 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | right<left,right+1 | ||
left=4;right=8 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | right<left,right+1 | ||
left=4;right=9 | 1 | 2 | 3 | 3 | 10 | 1 | 3 | 3 | 5 | ret=[left+1:right]=[1,3,3,5]=4 | ||
left=5;right=9 | 结束循环 |