2021-02-28:給定一個整型數組arr,和一個整數num。某個arr中的子數組sub,若是想達標,必須知足:sub中最大值 – sub中最小值 <= num,返回arr中達標子數組的數量。java
福哥答案2021-02-28:git
採用兩個雙端隊列,存序號。maxWindow從大到小,minWindow從小到大。
1.兩個雙端隊列同時右擴。當最大值-最小值大於sum,退出循環。
2.計數。
3.刪除雙端隊列左邊的過時序號。
有代碼。github
代碼用golang編寫,代碼以下:golang
package main import ( "container/list" "fmt" ) func main() { arr := []int{ 1, 2} sum := 6 ret := num(arr, sum) fmt.Println(ret) } func num(arr []int, sum int) int { arrLen := len(arr) if arrLen == 0 || sum < 0 { return 0 } count := 0 maxWindow := list.New().Init() minWindow := list.New().Init() R := 0 for L := 0; L < arrLen; L++ { for R < arrLen { //右擴 for maxWindow.Len() > 0 && arr[maxWindow.Back().Value.(int)] <= arr[R] { maxWindow.Remove(maxWindow.Back()) } maxWindow.PushBack(R) //右擴 for minWindow.Len() > 0 && arr[minWindow.Back().Value.(int)] >= arr[R] { minWindow.Remove(minWindow.Back()) } minWindow.PushBack(R) //若是最大值-最小值>sum,就不右擴了。 if arr[maxWindow.Front().Value.(int)]-arr[minWindow.Front().Value.(int)] > sum { break } else { R++ } } //計數 count += R - L //刪除過時窗口數據 if maxWindow.Front().Value.(int) == L { maxWindow.Remove(maxWindow.Front()) } if minWindow.Front().Value.(int) == L { minWindow.Remove(minWindow.Front()) } } return count }
執行結果以下:
數組