LeetCode 410. Split Array Largest Sum
方法一: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相关推荐
- 410. Split Array Largest Sum 分割数组的最大值
给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组.设计一个算法使得这 m 个子数组各自和的最大值最小. 注意: 数组长度 n 满足以下条件: 1 ≤ n ≤ 1000 ...
- leetcode 659. Split Array into Consecutive Subsequences
原题: You are given an integer array sorted in ascending order (may contain duplicates), you need to s ...
- LeetCode 659 Split Array into Consecutive Subsequences
LeetCode Brute Force的方法就是把维护这些字串,每次来新的就加入到符合条件的但是最短的字串中去. 因为不需要求这些字串,可以做一些优化,用字串最后一位数作为key,把长度存入一个di ...
- 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 ...
- 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 ...
- LeetCode—494. 目标和(Target Sum)——分析及代码(Java)
LeetCode-494. 目标和[Target Sum]--分析及代码[Java] 一.题目 二.分析及代码 1. 动态规划 (1)思路 (2)代码 (3)结果 2. 动态规划+节省空间 (1)思路 ...
- [勇者闯LeetCode] 189. Rotate Array
[勇者闯LeetCode] 189. Rotate Array Description Rotate an array of n elements to the right by k steps. F ...
- 力扣215:数组中的第K个最大元素 (leetcode 215:Kth Largest Element In An Array)
题目链接:https://leetcode.cn/problems/kth-largest-element-in-an-array 目录: 一.题目描述 1.中文 2.英文 二.解决方法 1.直接排序 ...
- leetcode 813. Largest Sum of Averages | 813. 最大平均值和的分组(暴力递归->傻缓存->DP)
题目 https://leetcode.com/problems/largest-sum-of-averages/ 题解 好久不 dp 了,来一道快乐的 dp 保持手感. 经典的暴力递归 -> ...
最新文章
- 妥~阿里程序员常用的 15 款开发者工具
- 应用安全与微软SDL-IT流程
- linux安装anaconda3提前so,Linux安装anaconda3
- linux 安装程序丢失链接动态库,Linux安装软件过程中提示缺少动态链接库.so的解决方法...
- 【caffe学习】caffe第二个比较典型的识别例子CIFAR_10的运行详解
- php -- php数组相关函数
- JavaWeb——拦截器HandlerInterceptor
- IDEA导入eclipse项目并部署到tomcat
- WPS删除多余空白页
- FPS 每秒传输帧数(Frames Per Second)
- word:回车替换成空格
- linux灵活提取ip脚本
- 关于python3的input函数和int()强制转换
- 大话云时代rac_“音乐隐士”沈以诚:他在网易云音乐为什么这么火?
- wchar_t的用法
- 海贼王经典语录(转)
- 服务器域名解析步骤总结
- 哈哈哈哈~山野村夫大进展
- VSCode 配置 C++ 环境
- 大数据从入门到实战 - 第3章 MapReduce基础实战
热门文章
- ansys如何删除线_PR学习之旅:PR预设如何导入,保存和效果重命名呢?诀窍很简单...
- 计算机与程序设计基础 vb,《VB程序设计基础》第4章 函数与过程
- vue图片滚动抽奖_Vue项目开发-仿蘑菇街电商APP
- 同一个接口Jmeter取不到结果
- 软件测试工程师如何编写一篇杀手级简历?
- 怎么利用c 语言编程进行进制计算,编程达人 《汇编、C语言基础教程》第一章 进制1.1 进制的定义(连载)...
- java监听表变化_「Java Web开发」Filte(过滤器)、Listener(监听器)
- 如歌将两个数组合并_将数组数据拆分后再合并,作为字典的键,实现多条件数据汇总...
- c语言输入y循环n结束,大佬们帮帮忙 帮我改改 怎样能在输入Y后 再次进行for循环...
- python编辑excel文件_python自动化之修改excel(包括xls文件和xlsx文件)