最大值减去最小值小于或等于num的子数组数量
題目:給定數組arr和整數num,共返回有多少個子數組滿足如下情況:子數組中的最大值減去最小值小于或等于num。
要求,時間復雜度O(N)。
基本思路:
首先明確兩點:
1、如果子數組arr[i…j]滿足條件,那么arr[i…j]中的子數組一定也滿足條件。
2、如果子數組arr[i…j]不滿足條件,那么包含arr[i…j]的子數組一定也不滿足條件。
使用兩個雙端隊列qmin和qmax,qmin用來維護子數組arr[i…j]的最小值更新,qmax用來維護子數組arr[i…j]的最大值更新。隊頭表示的就是子數組arr[i…j]的最小(大)值。生成兩個整型變量i和j,用于表示子數組的范圍,即arr[i…j]。整型變量res表示所有滿足條件的子數組數量。初始時,i、j、res都為0。
令j不斷向右移動,表示arr[i…j]一直向右擴張,并不斷更新qmin和qmax。一旦出現arr[i…j]不滿足條件的情況,擴張停止,此時arr[i…j-1]、arr[i…j-2]、arr[i…j-3]…arr[i…i]一定滿足條件。即所有必須以arr[i]開頭的滿足條件的子數組數量為j - i。所以令 res += j - i。
向右擴張停止后,令i向右移動一個單位,表示開始考慮以arr[i+1]開頭的滿足條件的子數組數量,更新qmin、qmax。接下來的過程和上述一樣。
所有的下標值最多進qmax和qmin一次,出qmax和qmin一次。i和j的值也不斷增加,并且從來不減小,所以整個時間復雜度為O(N)
def getNum(L,num):if L == None or len(L) < 1 or num <0 :returnqmin = []qmax = []i = 0j = 0res = 0while i < len(L):while j < len(L):while len(qmin)!=0 and L[qmin[-1]] >= L[j]:qmin.pop()qmin.append(j)while len(qmax)!=0 and L[qmax[-1]] <= L[j]:qmax.pop()qmax.append(j)if L[qmax[0]] - L[qmin[0]] > num:breakj +=1res += j-1if qmin[0] == i:qmin.pop(0)if qmax[0] == i:qmax.pop(0)i +=1return res
?
總結
以上是生活随笔為你收集整理的最大值减去最小值小于或等于num的子数组数量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 生成窗口最大值数组
- 下一篇: 子数组的最大累加和问题