2021-07-10:请返回arr中,求子数组的累加和,是<=K的并且是最大的。返回这个最大的累加和。
福大大 答案2021-07-10:
时间紧。见代码。
时间复杂度:O(N*logN)。空间复杂度:O(N)。
代码用golang编写。代码如下:
package main import ( "fmt" "math" "sort" ) func main() { arr := []int{1, 4, -3, 4, -5} ret := getMaxLessOrEqualK(arr, 7000) fmt.Println(ret) } // 请返回arr中,求个子数组的累加和,是<=K的,并且是最大的。 // 返回这个最大的累加和 func getMaxLessOrEqualK(arr []int, K int) int { // 记录i之前的,前缀和,按照有序表组织 set := make([]int, 0) map0 := make(map[int]struct{}) // 一个数也没有的时候,就已经有一个前缀和是0了 set = append(set, 0) map0[0] = struct{}{} max := math.MinInt64 sum := 0 // 每一步的i,都求子数组必须以i结尾的情况下,求个子数组的累加和,是<=K的,并且是最大的 for i := 0; i < len(arr); i++ { sum += arr[i] // sum -> arr[0..i]; sort.Ints(set) index := NearestIndex(set, sum-K) if index != -1 { max = getMax(max, sum-index) } if _, ok := map0[sum]; !ok { set = append(set, sum) // 当前的前缀和加入到set中去 map0[sum] = struct{}{} } } return max } func getMax(a int, b int) int { if a > b { return a } else { return b } } // 在arr上,找满足>=value的最左位置 func NearestIndex(arr []int, v int) int { L := 0 R := len(arr) - 1 index := -1 // 记录最左的对号 for L <= R { mid := L + (R-L)>>1 if arr[mid] >= v { index = mid R = mid - 1 } else { L = mid + 1 } } return index }
执行结果如下:
左神java代码