2021-03-31:配列arrが与えられ、値vが与えられました。平均値がv以下である最長のサブ配列の長さを見つけます。

2021-03-31:配列arrが与えられ、値vが与えられました。平均値がv以下である最長のサブ配列の長さを見つけます。

フーダの答え2021-03-31:

この質問は、昨日の質問の変形です。配列の各要素からvを減算し、最長のサブ配列の長さ<= 0を見つけます。
1.プレフィックスと+順序付きリスト。時間計算量はO(N * lgN)です。コードはありません。
2.スライディングウィンドウ。時間計算量はO(N)です。この質問は自然の知恵では想像できず、敏感さが必要です。コードがあります。
配列の各要素からvを引きます。
minSum配列、最小の累積合計、iで始まる最小の値。
最小値であるiで始まるminSumEnd配列。ここで、は右の境界です。
スライディングウィンドウを使用すると、右のポインタは一度に複数の位置に移動し、左のポインタは一度に1つの位置に移動します。
2つのforループが使用されますが、右ポインターはフォールバックしないため、複雑さはO(N)です。

コードはgolangで書かれています。コードは次のように表示されます。

package main

import "fmt"

//https://github.com/algorithmzuo/algorithmbasic2020/blob/master/src/class40/Code04_AvgLessEqualValueLongestSubarray.java
func main() {
    arr := []int{1000, -10, 60, -60, 3, 1, -2, 1, 10}
    v := 5
    ret := ways1(arr, v)
    fmt.Println(ret)

}

func ways1(arr []int, v int) int {
    arrLen := len(arr)
    if arrLen == 0 {
        return 0
    }
    //数组的所有值都减掉平均值
    for i := 0; i < arrLen; i++ {
        arr[i] -= v
    }

    //最小累加和数组
    //最小累加和数组的右边界
    minSums := make([]int, arrLen)
    minSumEnds := make([]int, arrLen)
    minSums[arrLen-1] = arr[arrLen-1]
    minSumEnds[arrLen-1] = arrLen - 1
    for i := arrLen - 2; i >= 0; i-- {
        if minSums[i+1] < 0 {
            minSums[i] = arr[i] + minSums[i+1]
            minSumEnds[i] = minSumEnds[i+1]

        } else {
            minSums[i] = arr[i]
            minSumEnds[i] = i
        }
    }

    R := 0
    sum := 0
    ans := 0
    for L := 0; L < arrLen; L++ {
        //R循环右扩
        for R < arrLen && sum+minSums[R] <= 0 {
            sum += minSums[R]
            R = minSumEnds[R] + 1
        }

        //统计答案
        ans = getMax(ans, R-L)

        //L右扩前,需要处理
        if R > L {
            sum -= arr[L]
        } else {
            R = L + 1
        }
    }

    //数组修改了,需要还原
    for i := 0; i < arrLen; i++ {
        arr[i] += v
    }

    return ans
}
func getMax(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

実行結果は以下のとおりです。

画像


神のJavaコードコメントを残しました

おすすめ

転載: blog.51cto.com/14891145/2678755