LeetCode 410. Split Array Largest Sum (hard)(最大值最小化)

题目链接:点击这里
在这里插入图片描述

二分的精髓:函数单调性 + 计算内容重复

二分法的难点在于如何建模和check()条件, 其中可能会套用其他算法或者数据结构。

这里 a n s ans m m 是单调、相关的,所以,考虑在 [ 0 , s u m ] [0,sum] 范围内二分找到一个 a n s ans 满足题目要求。

本题会爆掉int

AC代码:

class Solution {
public:
    //问题变为:当最大值为mid时,求m最小是多少。
    //贪心策略:能放则放。
    bool check(long long mid, vector<int>& nums, int m)
    {
        long long sum = 0;
        int cnt = 0;
        for(int i = 0; i < nums.size(); i++)
        {
            if(sum + nums[i] > mid)
            {
                cnt++;
                if(nums[i] > mid) return false;
                sum = nums[i];
            }
            else
                sum += nums[i];
        }
        return cnt < m;
    }

    int splitArray(vector<int>& nums, int m) {
        long long sum = 0;
        for(int i = 0; i < nums.size(); i++)
            sum += nums[i];
        
        long long L = 0, R = sum, mid, ans = 0; //[L,R]
        while(L <= R)
        {
            mid = L+(R-L)/2;
            if(check(mid, nums, m))
            {
                ans = mid;
                R = mid - 1;
            }
            else
            {
                L = mid + 1;
            }
        }
        return ans;
    }
};

注意本题 a n s ans m m 是负相关的,check()函数与主函数的逻辑关系要理清。

AC代码:

class Solution {
public:
    //问题变为:当最大值为mid时,求m最小是多少。
    //贪心策略:能放则放。
    //当前的mid小于等于时返回true,当前的mid大于时返回false
    bool check(long long mid, vector<int>& nums, int m)
    {
        long long sum = 0;
        int cnt = 0;
        for(int i = 0; i < nums.size(); i++)
        {
            if(sum + nums[i] >= mid)
            {
                cnt++;
                if(nums[i] >= mid) return true;
                sum = nums[i];
            }
            else
                sum += nums[i];
        }
        return cnt >= m;
    }

    int splitArray(vector<int>& nums, int m) {
        long long sum = 0;
        for(int i = 0; i < nums.size(); i++)
            sum += nums[i];
        
        long long L = 0, R = sum, mid, ans = 0; //[L,R]
        while(L <= R)
        {
            mid = L+(R-L)/2;
            if(check(mid, nums, m))
            {
                ans = mid;
                L = mid + 1;
            }
            else
            {
                R = mid - 1; 
            }
        }
        return ans;
    }
};
发布了690 篇原创文章 · 获赞 103 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/104065462