方法一:DFS+Memoization

某种程度来说本题和 Word Break 很像。直接dfs暴力做肯定会超时,加上memoization即可。

dfs(start, m, ...) 表示从index start开始,分成m组的minmax值。

时间复杂度 比较复杂,应该和DP一样是 O(n^2*m)

class Solution {
public:int splitArray(vector<int>& nums, int m) {int n=nums.size();// sum[i] - sum of first i itemsvector<long> sum(n+1,0);for (int i=1;i<=n;++i){sum[i] = sum[i-1]+nums[i-1];}vector<vector<long>> memo(n,vector<long>(m+1,-1));return dfs(0,m,nums,sum,memo);}// start - start indexlong dfs(int start, int m, vector<int> &nums, vector<long> &sum, vector<vector<long>> &memo){if (m==1) return sum[nums.size()]-sum[start];if (memo[start][m]!=-1) return memo[start][m];long minmax=LONG_MAX;for (int i=start+1;i<nums.size();++i){minmax = min(minmax, max(sum[i]-sum[start], dfs(i,m-1,nums,sum,memo)));}return memo[start][m]=minmax;}
};

方法二:DP

dp[i][j] 表示前i个分成j组的minmax的值。

dp[i][j] = min_k{ max(dp[k][j-1], a[k]+...+a[i-1]) }  (0<=k<i)

corner case: dp[i][j] = INT_MAX (j>i),  dp[i][1] = sum[i]

前i个其实最多只能分为i份,所以如果 j>i,不可能。设为INT_MAX就不会影响到最小值。

因此可以将dp全部初始化为INT_MAX,而且 只要将 dp[0][0] 设为0,dp[i][1] = sum[i]也可以被整合进for循环里。

当然,按照corner case初始化也是可以的。而且循环k的时候也可以从后向前,如果presum太大可以提前结束循环。

https://leetcode.com/problems/split-array-largest-sum/discuss/89838/C++-DP-SOLUTION

时间复杂度 O(n^2*m)

class Solution {
public:int splitArray(vector<int>& nums, int m) {int n=nums.size();// dp[i][j] - the minmax value of dividing first i items into j parts// dp[0][j] = INT_MAX,  dp[i][1] = sum[i];// dp[i][j] = min_k max(dp[k][j-1], a[k]+...+a[i-1])  (0<=k<i)vector<vector<long>> dp(n+1,vector<long>(m+1,INT_MAX));// sum[i] - sum of first i itemsvector<long> sum(n+1,0);for (int i=1;i<=n;++i){sum[i] = sum[i-1]+nums[i-1];}dp[0][0] = 0;for (int i=1;i<=n;++i){for (int j=1;j<=m;++j){for (int k=0;k<i;++k){dp[i][j] = min(dp[i][j], max(dp[k][j-1], sum[i]-sum[k]));}}}return dp[n][m];}
};

方法三:Binary Search+Greedy

原题是Optimization问题,要找到最大subarray的最小值。我们可以先解决对应的Search Problem,然后用二分解决优化问题。即,给定一个上限cap,判断能否在满足要求的情况下(最大subarray<=cap),将数组分为m段。

这个Search Problem可以用Greedy来做,如果subarray sum>cap,说明需要新开一段。

二分部分标准写法,搜索区间是 [max{nums[i]}, sum_{nums[i]}],如果canSplit(mid),我们需要找更小的值,high=mid,如果不行,那就放松cap,low=mid+1。同时也保证了解一直在搜索区间里。

当然另一种写法 while (low<=high); low=mid+1; high=low-1; 当然也是可以的,搜索区间是 [low,high],解区间是[low,high+1]。可以复习一下 Binary Search。

时间复杂度 O(n*log(sum(nums) - max(nums)))

class Solution {
public:int splitArray(vector<int>& nums, int m) {long low=0, high=0;for (long num:nums){low = max(low,num);high += num;}while (low<high){long mid=(low+high)/2;if (canSplit(mid,nums,m))high = mid;elselow = mid+1;}return low;}bool canSplit(long cap, vector<int> &nums, int m){int count=1;long sum=0;for (int num:nums){sum += num;if (sum>cap){++count;if (count>m) return false;sum = num;}}return true;}
};

转载于:https://www.cnblogs.com/hankunyan/p/10988054.html

LeetCode 410. Split Array Largest Sum相关推荐

  1. 410. Split Array Largest Sum 分割数组的最大值

    给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组.设计一个算法使得这 m 个子数组各自和的最大值最小. 注意: 数组长度 n 满足以下条件: 1 ≤ n ≤ 1000 ...

  2. leetcode 659. Split Array into Consecutive Subsequences

    原题: You are given an integer array sorted in ascending order (may contain duplicates), you need to s ...

  3. LeetCode 659 Split Array into Consecutive Subsequences

    LeetCode Brute Force的方法就是把维护这些字串,每次来新的就加入到符合条件的但是最短的字串中去. 因为不需要求这些字串,可以做一些优化,用字串最后一位数作为key,把长度存入一个di ...

  4. LeetCode 905 Sort Array By Parity--Java stream,Python lambda表达式一行 解法

    题目地址:Sort Array By Parity - LeetCode Given an array A of non-negative integers, return an array cons ...

  5. leetcode 330. Patching Array | 1798. Maximum Number of Consecutive Values You Can Make

    1798. Maximum Number of Consecutive Values You Can Make | 1798. 你能构造出连续值的最大数目 https://leetcode.com/p ...

  6. LeetCode—494. 目标和(Target Sum)——分析及代码(Java)

    LeetCode-494. 目标和[Target Sum]--分析及代码[Java] 一.题目 二.分析及代码 1. 动态规划 (1)思路 (2)代码 (3)结果 2. 动态规划+节省空间 (1)思路 ...

  7. [勇者闯LeetCode] 189. Rotate Array

    [勇者闯LeetCode] 189. Rotate Array Description Rotate an array of n elements to the right by k steps. F ...

  8. 力扣215:数组中的第K个最大元素 (leetcode 215:Kth Largest Element In An Array)

    题目链接:https://leetcode.cn/problems/kth-largest-element-in-an-array 目录: 一.题目描述 1.中文 2.英文 二.解决方法 1.直接排序 ...

  9. leetcode 813. Largest Sum of Averages | 813. 最大平均值和的分组(暴力递归->傻缓存->DP)

    题目 https://leetcode.com/problems/largest-sum-of-averages/ 题解 好久不 dp 了,来一道快乐的 dp 保持手感. 经典的暴力递归 -> ...

最新文章

  1. 妥~阿里程序员常用的 15 款开发者工具
  2. 应用安全与微软SDL-IT流程
  3. linux安装anaconda3提前so,Linux安装anaconda3
  4. linux 安装程序丢失链接动态库,Linux安装软件过程中提示缺少动态链接库.so的解决方法...
  5. 【caffe学习】caffe第二个比较典型的识别例子CIFAR_10的运行详解
  6. php -- php数组相关函数
  7. JavaWeb——拦截器HandlerInterceptor
  8. IDEA导入eclipse项目并部署到tomcat
  9. WPS删除多余空白页
  10. FPS 每秒传输帧数(Frames Per Second)
  11. word:回车替换成空格
  12. linux灵活提取ip脚本
  13. 关于python3的input函数和int()强制转换
  14. 大话云时代rac_“音乐隐士”沈以诚:他在网易云音乐为什么这么火?
  15. wchar_t的用法
  16. 海贼王经典语录(转)
  17. 服务器域名解析步骤总结
  18. 哈哈哈哈~山野村夫大进展
  19. VSCode 配置 C++ 环境
  20. 大数据从入门到实战 - 第3章 MapReduce基础实战

热门文章

  1. ansys如何删除线_PR学习之旅:PR预设如何导入,保存和效果重命名呢?诀窍很简单...
  2. 计算机与程序设计基础 vb,《VB程序设计基础》第4章 函数与过程
  3. vue图片滚动抽奖_Vue项目开发-仿蘑菇街电商APP
  4. 同一个接口Jmeter取不到结果
  5. 软件测试工程师如何编写一篇杀手级简历?
  6. 怎么利用c 语言编程进行进制计算,编程达人 《汇编、C语言基础教程》第一章 进制1.1 进制的定义(连载)...
  7. java监听表变化_「Java Web开发」Filte(过滤器)、Listener(监听器)
  8. 如歌将两个数组合并_将数组数据拆分后再合并,作为字典的键,实现多条件数据汇总...
  9. c语言输入y循环n结束,大佬们帮帮忙 帮我改改 怎样能在输入Y后 再次进行for循环...
  10. python编辑excel文件_python自动化之修改excel(包括xls文件和xlsx文件)