"""
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 | 結束循環 |