LeetCode 题解 | 410. 分割数组的最大值(最大值最小化 二分答案 C++)

题目描述(困难难度)

原题链接
LeetCode 题解 | 410. 分割数组的最大值(最大值最小化 二分答案 C++)_第1张图片

算法

(二分答案) O ( n l o g n ) O(nlogn) O(nlogn)

二分答案经典题

所求的最大子数组和在 [max(nums), sum(nums)] 之内,但是我其实稍微扩大范围也能做,但要注意check函数里要多一句判断语句if (nums[i] > x) return false;

Saturday, May 9, 2020 14:47:37
更新:建议还是求出区间的精确范围,因为check函数那个判断条件很容易忘记写

C++代码1

class Solution {
public:
    // 最大值的最小化问题
    typedef long long LL;
    bool check(vector<int> & nums, long long x, int m) {     
        LL sum = 0;
        m --;
        for (int i = 0; i < nums.size(); i ++) {
            sum += nums[i];
            if (sum > x) {
                sum = nums[i];
                // 因为我边界取的是无穷,所以如果单独一天都比x大了,那x一定不是最大值
                if (nums[i] > x) return false; 
                m --;
            }  
        }
        return m >= 0;
    }

    int splitArray(vector<int>& nums, int m) {
        LL l = -1e9, r = 1e12;
        while (l < r) {
            LL mid = l + r >> 1;
            if (check(nums, mid, m)) r = mid;
            else l = mid + 1;
        }
        return r;
    }
};

C++代码2

这段代码,我求出来了左边界max(nums[i]),目的是保证x >= nums[i]

class Solution {
public:
    // 最大值的最小化问题
    typedef long long LL;
    bool check(vector<int> & nums, long long x, int m) {     
        LL sum = 0;
        m --;
        for (int i = 0; i < nums.size(); i ++) {
            sum += nums[i];
            if (sum > x) {
                sum = nums[i];
                // 因为我边界取的是无穷,所以如果单独一天都比x大了,那x一定不是最大值
                // if (nums[i] > x) return false; 
                m --;
            }  
        }
        return m >= 0;
    }

    int splitArray(vector<int>& nums, int m) {
        LL l = *max_element(nums.begin(),nums.end()), r = 1e12;
        while (l < r) {
            LL mid = l + r >> 1;
            if (check(nums, mid, m)) r = mid;
            else l = mid + 1;
        }
        return r;
    }
};

LeetCode 题解 | 410. 分割数组的最大值(最大值最小化 二分答案 C++)_第2张图片

你可能感兴趣的:(LeetCode)