Leetcode 410. Split Array Largest Sum 劃分陣列 解題報告
阿新 • • 發佈:2019-02-09
1 解題思想
首先宣告下,本文這些內容,基本是dicuss的來的
題目意思是,給一個數組,需要劃分成m份,讓你找出一種劃分方式,使得劃分成m份後,最大的那一個區間的數值最小
這道題discuss上說的是2分查詢,我也確實想不到更好的方式:
1、首先這個區間的值肯定是在[最大的單個數,所有陣列只和] 中間的
2、利用二分查詢的思想進行查詢,查詢範圍和1的標註那個一樣,必須要那個
3、查詢時用valid驗證,對於當前這個值,能否合法的劃分出來?是多了還是少了,所謂的不合法就是說對於給定值,必須要劃分了多餘m個區間,才能讓給定值是所有劃分區間裡最大值小於等於給定值
2 原題
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.
Examples:
Input:
nums = [1 ,2,3,4,5]
m = 2
Output:
9
Explanation:
There are four ways to split nums into two subarrays.
The best way is to split it into [1,2,3] and [4,5],
where the largest sum among the two subarrays is only 9.
3 AC解
來自discuss
public class Solution {
/**
* 這個數肯定介於最大的那一個單值和所有元素只和的中間
* */
public int splitArray(int[] nums, int m) {
long sum = 0;
int max = 0;
for(int num: nums){
max = Math.max(max, num);
sum += num;
}
return (int)binarySearch(nums, m, sum, max);
}
//二分查詢
private long binarySearch(int[] nums, int m, long high, long low){
long mid = 0;
while(low < high){
mid = (high + low)/2;
//驗證是否滿足,也就是這麼大的值有可能出現麼
if(valid(nums, m, mid)){
high = mid;
}else{
low = mid + 1;
}
}
return high;
}
/**
* 驗證這個值是否合法
* */
private boolean valid(int[] nums, int m, long max){
int cur = 0;
int count = 1;
//是否有多餘m個片段or區間,大於給定值的max的,如果有了,那麼就不合法了,因為這樣劃分就不止m個,及max太小
for(int num: nums){
cur += num;
if(cur > max){
cur = num;
count++;
if(count > m){
return false;
}
}
}
return true;
}
}