2021-03-30: Given an unordered array arr composed of integers, the value may be positive, negative, or 0. Given an integer value K,

2021-03-30: Given an unordered array arr composed of integers, the value may be positive, negative, or 0. Given an integer value K, find which sub-array of all sub-arrays of arr has the cumulative sum <=K and is the largest in length. Return its length.

Fu Da's answer 2021-03-30:

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.
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, the code is as follows:

package main

import "fmt"

func main() {
    arr := []int{1000, -10, 60, -60, 3, 1, -2, 1, 10}
    k := 1
    ret := maxLengthAwesome(arr, k)
    fmt.Println(ret)

}
func maxLengthAwesome(arr []int, k int) int {
    if len(arr) == 0 {
        return 0
    }
    minSums := make([]int, len(arr))
    minSumEnds := make([]int, len(arr))
    minSums[len(arr)-1] = arr[len(arr)-1]
    minSumEnds[len(arr)-1] = len(arr) - 1
    for i := len(arr) - 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
        }
    }

    // 迟迟扩不进来那一块儿的开头位置
    end := 0
    sum := 0
    ans := 0
    for i := 0; i < len(arr); i++ {
        // while循环结束之后:
        // 1) 如果以i开头的情况下,累加和<=k的最长子数组是arr[i..end-1],看看这个子数组长度能不能更新res;
        // 2) 如果以i开头的情况下,累加和<=k的最长子数组比arr[i..end-1]短,更新还是不更新res都不会影响最终结果;
        for end < len(arr) && sum+minSums[end] <= k {
            sum += minSums[end]
            end = minSumEnds[end] + 1
        }
        ans = getMax(ans, end-i)
        if end > i { // 还有窗口,哪怕窗口没有数字 [i~end) [4,4)
            sum -= arr[i]
        } else { // i == end,  即将 i++, i > end, 此时窗口概念维持不住了,所以end跟着i一起走
            end = i + 1
        }
    }
    return ans
}

func maxLength(arr []int, k int) int {
    h := make([]int, len(arr)+1)
    sum := 0
    h[0] = sum
    for i := 0; i != len(arr); i++ {
        sum += arr[i]
        h[i+1] = getMax(sum, h[i])
    }
    sum = 0
    res := 0
    pre := 0
    llen := 0
    for i := 0; i != len(arr); i++ {
        sum += arr[i]
        pre = getLessIndex(h, sum-k)
        if pre != -1 {
            llen = i - pre + 1
        }
        res = getMax(res, llen)
    }
    return res
}
func getLessIndex(arr []int, num int) int {
    low := 0
    high := len(arr) - 1
    mid := 0
    res := -1
    for low <= high {
        mid = (low + high) / 2
        if arr[mid] >= num {
            res = mid
            high = mid - 1
        } else {
            low = mid + 1
        }
    }
    return res
}
func getMax(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

The execution results are as follows:
Insert picture description here


Left God java code
comment

Guess you like

Origin blog.51cto.com/14891145/2677833