1712. Ways to Split Array Into Three Subarrays

A split of an integer array is good if:

  • The array is split into three non-empty contiguous subarrays - named leftmidright 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 of good ways to split nums. As the number may be too large, return it modulo 109 + 7.

Example 1:

Input: nums = [1,1,1]
Output: 1
Explanation: The only good way to split nums is [1] [1] [1].

Example 2:

Input: nums = [1,2,2,2,5,0]
Output: 3
Explanation: There are three good ways of splitting nums:
[1] [2] [2,2,5,0]
[1] [2,2] [2,5,0]
[1,2] [2,2] [5,0]

Example 3:

Input: nums = [3,2,1]
Output: 0
Explanation: There is no good way to split nums.

Constraints:

  • 3 <= nums.length <= 105
  • 0 <= nums[i] <= 104

题目:给定一串数组,将数组分成三部分,第一部分总和小于等于第二部分,第二部分总和小于等于第三部分。问共有多少种分割方法。

思路:求总和,先将数组整体求和。每个元素点i都是前面0~i元素点的总和。然后从前往后遍历,先确定第一个子数组,找到第二个子数组和第三个子数组的最前和最后分割点,中间的差值加入到结果中。找分割点时用二分法,双指针的题中,lower_bound和upper_bound简直不要太好用哦~

代码:

class Solution {
public:
    int waysToSplit(vector<int>& nums) {
        for(int i = 1; i < nums.size(); i++){
            nums[i] += nums[i-1];
        }
        int res = 0, total = nums.back(), mod = 1000000007;
        for(int i = 0; i < nums.size()-2; i++){
            if(nums[i] > total/3) return res;
            int start = lower_bound(nums.begin()+i+1, nums.end(), 2*nums[i])-nums.begin();
            int end = upper_bound(nums.begin()+start, nums.end(), (total+nums[i])/2)-nums.begin();
            if(end == nums.size()) end--; //全零数组找upper_bound时会找到数组结尾,但第三个不能是空数组,所以需要减一。
            res = (res - start + end) % mod;
        }
        return res;
    }
};

time: O(N*logN), space:O(1);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值