2021-03-31: Given an array arr, given a value v. Find the length of the longest sub-array whose average value is less than or equal to v.

2021-03-31: Given an array arr, given a value v. Find the length of the longest sub-array whose average value is less than or equal to v.

Fu Da's answer 2021-03-31:

This question is a variant of yesterday's question. Subtract v from each element of the array, and then find the length of the longest sub-array <=0.
1. Prefix and + ordered list. The time complexity is O(N*lgN). No code.
2. Sliding window. The time complexity is O(N). This question cannot be imagined with natural wisdom and requires sensitivity. There is code.
Subtract v from each element of the array.
The minSum array, the smallest cumulative sum, the smallest value starting with i.
The minSumEnd array, the minimum value starting with i, where is the right boundary.
Using a sliding window, the right pointer moves multiple positions at a time, and the left pointer moves one position at a time.
Although two for loops are used, the right pointer does not fall back, so the complexity is O(N).

The code is written in golang. code show as below:

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
    }
}

The execution results are as follows:

image


Left God java code
comment

Guess you like

Origin blog.51cto.com/14891145/2678755