LeetCode 410. 分割数组的最大值

题目描述:

给定一个非负整数数组和一个整数 m,你需要将这个数组分成 个非空的连续子数组。设计一个算法使得这 个子数组各自和的最大值最小。

注意:
数组长度 满足以下条件:

  • 1 ≤ n ≤ 1000
  • 1 ≤ m ≤ min(50, n)

示例:

输入:
nums = [7,2,5,10,8]
m = 2

输出:
18

解释:
一共有四种方法将nums分割为2个子数组。
其中最好的方式是将其分为[7,2,5][10,8],
因为此时这两个子数组各自的和的最大值为18,在所有情况中最小。


错误思路:

最开始直接想到的方法是分组:   数1|数2|数3|数4 数5 数6 数7...........  分割线为分组情况, 然后记录下分割线的位置,从最右边的分割线开始,依次将分割线向右边移动,每次判断子数组和的最大值,如果减小就移动下一条分割线,于是很快写出了这样的代码。

JavaScript:

/**
 * @param {number[]} nums
 * @param {number} m
 * @return {number}
 */
var splitArray = function(nums, m) {
        var splitArr=[];
        var valueArr=[];
        var len=nums.length;
        var max=0;
        for(var i=0;i0;i--)
        {
            var st=splitArr[i];
            var ed=splitArr[i+1];
            for(var j=st;j

LeetCode 410. 分割数组的最大值_第1张图片

但是运行的时候不能通过全部的测试用例,分析了一下逻辑,发现陷入了局部最优解。


正确思路:

采用动态规划。用一个二维数组记录情况,记录分组里面子数组各自和的最大值最小的值。dp[i][j]表示将输入数组的前j个数分为i 组。其中有dp[0][0]=0。dp[i-1][k]表示将k个数分为i-1组,j-k个数单独分为一组。那么刚好合起来就是i组。 转变为找所有分组里面子数组和的最大值。在这些最大值里面找到最小的值。

JavaScript:

/**
 * @param {number[]} nums
 * @param {number} m
 * @return {number}
 */
var splitArray = function(nums, m) {
     //动态规划
    var len=nums.length;
    var dp=[];
    var maxArr=[0];
    nums.forEach(function(item,index){
        maxArr[index+1]=maxArr[index]+item;
    });
    for(var i=0;i<=m;i++)
    {
        dp[i]=[];
        for(var j=0;j<=len;j++)
        {
            dp[i][j]=maxArr[maxArr.length-1];
        }
    }

    dp[0][0]=0;
    for(var i=1;i<=m;i++)
    {
        for(var j=1;j<=len;j++)
        {
            for(var k=i-1;k

你可能感兴趣的:(leetcode)