Leetcode (410) Split Array Largest Sum

  • 题目:

    Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays.

    Note:
    Given m satisfies the following constraint: 1 ≤ m ≤ length(nums) ≤ 14,000.

  • 题意:给定一个数组,不能改变数组中的数的位置,要求将数组分成m个部分,使得这m个部分的最大的和最小。

  • 思路:虽然题目是从动态规划分类下面找的,但是注意到最小化最大值立即就想到了二分的方法去处理了。
  • 二分处理思路:

    1. 目的是使得部分和的最大值最小,那么就可以枚举答案的值m,如果枚举出来的值能够达到,那么对于最终答案必然有 ansm
    2. 而实际上并不需要枚举所有m的值,因为对于值m,如果m不能满足那么大于m的值也必然不能满足,而如果m能够满足,那么必然存在小于等于m的值也满足——即二分可以解决
    3. 而要判断能不能够满足,因为数组中的数字位置不能够改变,因此只需要从头开始贪心求和,直到和大于m值时,就必然要划分多一个区间,最终要是需要的区间大于要求的,那必然不能满足(当然,如果出现某个数字比m大,也必然不能满足)
  • PS:二分方法的复杂度大约为O(nlog(sum))的,而因为sum一定不会超过long long,即O(64n)。而dp的方法估计为 O(n2) 评论区貌似也都是TLE的,就鸽了。。

  • 代码:

class Solution {
private:
    inline bool issatisfied(const vector<int>& nums, long long sum, int m)
    {
        int n = 1;
        long long acc=0;
        for (auto num: nums)
        {
            if (num > sum) return false;
            acc += num;
            if (acc > sum)
            {
                n++;
                acc = num;
            }
        }
        return n<=m && acc<=sum;
    }
public:
    int splitArray(vector<int>& nums, int m) {
        long long right = 0;
        for (auto num: nums)
        {
            right += num;
        }

        long long left=1;
        while (right != left)
        {
            long long mid = (left+right)>>1;
            if (issatisfied(nums, mid, m))
            {
                right=mid;
            }
            else
            {
                left=mid+1;
            }
        }
        return left;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值