The array is split into three non-empty contiguous subarrays - named left, mid, right respectively from left to right.
The sum of the elements in left is less than or equal to the sum of the elements in mid, and the sum of the elements in mid is less than or equal to the sum of the elements in right.
Given nums, an array of non-negative integers, return the number ofgood ways to splitnums. As the number may be too large, return it
modulo10^9 + 7.
We want to split the array into three contiguous parts such that sum(left) ≤ sum(mid) ≤ sum(right). By using prefix sums, we can efficiently compute subarray sums and use binary search to find valid split points.
classSolution {
public:int waysToSplit(vector<int>& nums) {
constint MOD =1e9+7;
int n = nums.size();
vector<int> pre(n+1);
for (int i =0; i < n; ++i) pre[i+1] = pre[i] + nums[i];
int ans =0;
for (int i =1; i <= n-2; ++i) {
int l = lower_bound(pre.begin()+i+1, pre.end()-1, 2*pre[i]) - pre.begin();
int r = upper_bound(pre.begin()+i+1, pre.end()-1, (pre[n]+pre[i])/2) - pre.begin();
if (l < r) ans = (ans + r - l) % MOD;
}
return ans;
}
};
import java.util.*;
classSolution {
publicintwaysToSplit(int[] nums) {
int n = nums.length, mod = 1_000_000_007;
int[] pre =newint[n+1];
for (int i = 0; i < n; i++) pre[i+1]= pre[i]+ nums[i];
int ans = 0;
for (int i = 1; i <= n-2; i++) {
int l = lowerBound(pre, i+1, n-1, 2*pre[i]);
int r = lowerBound(pre, i+1, n-1, (pre[n]+pre[i])/2+1);
if (l < r) ans = (ans + r - l) % mod;
}
return ans;
}
privateintlowerBound(int[] a, int l, int r, int x) {
while (l < r) {
int m = (l + r) / 2;
if (a[m]< x) l = m + 1;
else r = m;
}
return l;
}
}
classSolution {
funwaysToSplit(nums: IntArray): Int {
val n = nums.size
val mod = 1_000_000_007
val pre = IntArray(n+1)
for (i in0 until n) pre[i+1] = pre[i] + nums[i]
var ans = 0for (i in1..n-2) {
val l = lowerBound(pre, i+1, n, 2*pre[i])
val r = lowerBound(pre, i+1, n, (pre[n]+pre[i])/2+1)
if (l < r) ans = (ans + r - l) % mod
}
return ans
}
privatefunlowerBound(a: IntArray, l: Int, r: Int, x: Int): Int {
var left = l
var right = r
while (left < right) {
val m = (left + right) / 2if (a[m] < x) left = m + 1else right = m
}
return left
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from typing import List
classSolution:
defwaysToSplit(self, nums: List[int]) -> int:
from bisect import bisect_left, bisect_right
n = len(nums)
pre = [0]
for x in nums:
pre.append(pre[-1] + x)
ans =0 mod =10**9+7for i in range(1, n-1):
l = bisect_left(pre, 2*pre[i], i+1, n)
r = bisect_right(pre, (pre[n]+pre[i])//2, i+1, n)
if l < r:
ans = (ans + r - l) % mod
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
impl Solution {
pubfnways_to_split(nums: Vec<i32>) -> i32 {
let n = nums.len();
letmut pre =vec![0; n+1];
for i in0..n { pre[i+1] = pre[i] + nums[i]; }
letmut ans =0;
let m =1_000_000_007;
for i in1..n-1 {
let l = (i+1..n).find(|&j| pre[j] >=2*pre[i]).unwrap_or(n);
let r = (i+1..n).rfind(|&j| pre[j] <= (pre[n]+pre[i])/2).map_or(i+1, |x| x+1);
if l < r { ans = (ans + r - l) % m; }
}
ans
}
}