2021-02-28:給定一個整型數組arr,和一個整數num。某個arr中的子數組sub,若是想達標,必須知足:sub中最大值 – sub中最小值 <= num,返回arr中達標子數組的數量。

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
}

執行結果以下:
在這裏插入圖片描述數組


左神java代碼
評論url

相關文章
相關標籤/搜索