小旭讲解 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 ...
随机推荐
- o'Reill的SVG精髓(第二版)学习笔记——第六章
第六章:坐标系统变换 想要旋转.缩放或者移动图片到新的位置.可以给对应的SVG元素添加transform属性. 6.1 translate变换 可以为<use>元素使用x和y属性,以在特性 ...
- 关于ProjectServer调用PSI 报Error GeneralReadOnlyColumn (20005) - column TS_ACT_FINISH_DATE错的解决方案
TimesheetDataSet Table Actuals Row: TS_LINE_UID='f4b970f8-fb03-44d1-9997-cd31da42cb09' TS_ACT_START_ ...
- LeetCode13.罗马数字转整数 JavaScript
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并 ...
- 对AFNetworking的二次封装
HttpTool.h #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> typedef void(^HttpS ...
- c# LRU实现的缓存类
在网上找到网友中的方法,将其修改整理后,实现了缓存量控制以及时间控制,如果开启缓存时间控制,会降低效率. 定义枚举,移除时使用 public enum RemoveType { [ ...
- 正则表达式之——exec,match
刚开始接触正则,发现了一件有意思的事,我想要匹配正则,这下尴尬了- -,光知道正则表达式写法,并不知道正则如何才能获取匹配值. 慢慢摸索中... 找到答案!!! 正则匹配有两种方法: 一种是match ...
- CSS实现表单
效果图如下: HTML代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...
- reactor模式---事件触发模型
Reactor这个词译成汉语还真没有什么合适的,很多地方叫反应器模式,但更多好像就直接叫reactor模式了,其实我觉着叫应答者模式更好理解一些.通过了解,这个模式更像一个侍卫,一直在等待你的召唤. ...
- ELK 分布式日志实战
一. ELK 分布式日志实战介绍 此实战方案以 Elk 5.5.2 版本为准,分布式日志将以下图分布进行安装部署以及配置. 当Elk需监控应用日志时,需在应用部署所在的服务器中,安装Filebeat ...
- NAND Flash结构及驱动函数
目标:以NAND Flash K9F2G08U0M为例介绍其结构及其驱动程序的书写 1. 结构 由芯片手册中的图可知:K9F2G08U0M大小为2112Mbits(即 256MB = 2Gb ) 共有 ...