小旭讲解 LeetCode 53. Maximum Subarray 动态规划 分治策略
原题
Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
讲解
动态规划
视频@ 哔哩哔哩 动态规划 or YouTube 动态规划
通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
动态规划的性质
- 最优子结构(optimal sub-structure):如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
- 重叠子问题(overlapping sub-problem):动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。
状态转移方程
dp[i] = max(nums[i], nums[i] + dp[i - 1])
解释
- i代表数组中的第i个元素的位置
- dp[i]代表从0到i闭区间内,所有包含第i个元素的连续子数组中,总和最大的值
nums = [-2,1,-3,4,-1,2,1,-5,4]
dp = [-2, 1, -2, 4, 3, 5, 6, 1, 5]
时间复杂度
O(n)
参考
代码(C++)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
// boundary
if (nums.size() == ) return ;
// delares
vector<int> dp(nums.size(), );
dp[] = nums[];
int max = dp[];
// loop
for (int i = ; i < nums.size(); ++i) {
dp[i] = nums[i] > nums[i] + dp[i - ] ? nums[i] : nums[i] + dp[i - ];
if (max < dp[i]) max = dp[i];
}
return max;
}
};
分治策略
视频@ 哔哩哔哩 分治策略 or YouTube 分治策略
分治算法是一个解决复杂问题的好工具,它可以把问题分解成若干个子问题,把子问题逐个解决,再组合到一起形成大问题的答案。
这个技巧是很多高效算法的基础,如排序算法(快速排序、归并排序)
实现方式
循环递归
在每一层递归上都有三个步骤:
- 分解:将原问题分解为若干个规模较小,相对独立,与原问题形式相同的子问题。
- 解决:若子问题规模较小且易于解决 时,则直接解。否则,递归地解决各子问题。
- 合并:将各子问题的解合并为原问题的解。
注意事项
- 边界条件,即求解问题的最小规模的判定
示意图

递归关系式
T(n) = 2T(n/2) + n
可以利用递归树的方式求解其时间复杂度(其求解过程在《算法导论》中文第三版 P51有讲解)
时间复杂度
O(nlgn)
代码(C++)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
return find(nums, 0, nums.size() - 1);
}
int find(vector<int>& nums, int start, int end) {
// boundary
if (start == end) {
return nums[start];
}
if (start > end) {
return INT_MIN;
}
// delcare
int left_max = 0, right_max = 0, ml = 0, mr = 0;
int middle = (start + end) / 2;
// find
left_max = find(nums, start, middle - 1);
right_max = find(nums, middle + 1, end);
// middle
// to left
for (int i = middle - 1, sum = 0; i >= start; --i) {
sum += nums[i];
if (ml < sum) ml = sum;
}
// to right
for (int i = middle + 1, sum = 0; i <= end; ++i) {
sum += nums[i];
if (mr < sum) mr = sum;
}
// return
return max(max(left_max, right_max), ml + mr + nums[middle]);
}
};
原题:https://leetcode.com/problems/maximum-subarray
文章来源:胡小旭 => 小旭讲解 LeetCode 53. Maximum Subarray
小旭讲解 LeetCode 53. Maximum Subarray 动态规划 分治策略的更多相关文章
- [array] leetcode - 53. Maximum Subarray - Easy
leetcode - 53. Maximum Subarray - Easy descrition Find the contiguous subarray within an array (cont ...
- Leetcode#53.Maximum Subarray(最大子序和)
题目描述 给定一个序列(至少含有 1 个数),从该序列中寻找一个连续的子序列,使得子序列的和最大. 例如,给定序列 [-2,1,-3,4,-1,2,1,-5,4], 连续子序列 [4,-1,2,1] ...
- LN : leetcode 53 Maximum Subarray
lc 53 Maximum Subarray 53 Maximum Subarray Find the contiguous subarray within an array (containing ...
- leetcode 53. Maximum Subarray 、152. Maximum Product Subarray
53. Maximum Subarray 之前的值小于0就不加了.dp[i]表示以i结尾当前的最大和,所以需要用一个变量保存最大值. 动态规划的方法: class Solution { public: ...
- 41. leetcode 53. Maximum Subarray
53. Maximum Subarray Find the contiguous subarray within an array (containing at least one number) w ...
- LeetCode 53. Maximum Subarray(最大的子数组)
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- leetCode 53.Maximum Subarray (子数组的最大和) 解题思路方法
Maximum Subarray Find the contiguous subarray within an array (containing at least one number) whic ...
- [LeetCode] 53. Maximum Subarray 最大子数组 --动态规划+分治
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
- [LeetCode] 53. Maximum Subarray 最大子数组
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
随机推荐
- MapFile
MapFile是排序后的SequenceFile, 这个排序是由开发者来保证的, 不是内存实现. 相当于对key作了一个分块索引, 只针对key. 缺点 1.文件不支持复写操作,不能向已存在的Seq ...
- C#中的代码书写规范以及命名规范
C#代码书写规则: 1. 尽量使用接口,然后使用类实现接口,以提高程序的灵活性. 2.一行不要超过80个字符 3.尽量不要手动更改计算机生成的代码 4.关键的语句写注释 5.建议局部变量在最接近使用它 ...
- C#结构体和字节数组的转换函数
在通信过程中,一般我们都会操作到字节数组.特别是希望在不同语言编程进行操作的时候. 虽然C#提供了序列化的支持,不用字节数组也行.但操作字节数组肯定会碰到. 一般都会采用结构来表示字节数组.但结构 ...
- CALayer简介(转)
一.简单介绍 在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮,一个文本标签,一个文本输入框,一个图标等等,这些都是UIView. 其实UIView之所以能显示在屏幕上,完全 ...
- rest_framework --- APIView
一.什么是rest_framework 它是基于Django的,帮助我们快速开发符合RESTful规范的接口框架. 安装方式有很多种,可以通过pip,或者在pycharm中安装也可以 二.APIVie ...
- plupload批量上传分片(后台代码)
plupload批量上传分片功能, 对于文件比较大的情况下,plupload支持分片上传,后台代码如下: /** * * 方法:upLoadSpecialProgramPictrue * 方法说明:本 ...
- 选课(树形DP)
题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...
- 搭建两个节点的大数据集群-1.hdfs集群
0.规划 两个节点: ip 部署的程序 备注 192.168.56.2/bigdata.lzf namenode,datanode,NodeManager,hive,presto,mysql, ...
- windows下openresty中使用lua做接口转发、二次封装等
需求:根据客户需求,可以在ngx下 通过lua做接口二次封装再次转发给用户或第三方 场景:对返回值有要求的.接口屏蔽字段.或做一些业务上的验证等 1.windows直接下载openresty 解压即可 ...
- centos7中vsftp的搭建
开启vsftpd:service vsftpd start关闭vsftp:service vsftpd stop 安装vsftpd: yum -y install vsftpd 建立vsftpd帐号: ...
