原题

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 动态规划

通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

动态规划的性质

  1. 最优子结构(optimal sub-structure):如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
  2. 重叠子问题(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 分治策略

 

分治算法是一个解决复杂问题的好工具,它可以把问题分解成若干个子问题,把子问题逐个解决,再组合到一起形成大问题的答案。

这个技巧是很多高效算法的基础,如排序算法快速排序归并排序

实现方式

循环递归

在每一层递归上都有三个步骤:

  1. 分解:将原问题分解为若干个规模较小,相对独立,与原问题形式相同的子问题。
  2. 解决:若子问题规模较小且易于解决 时,则直接解。否则,递归地解决各子问题。
  3. 合并:将各子问题的解合并为原问题的解。

注意事项

  • 边界条件,即求解问题的最小规模的判定

示意图

递归关系式

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 动态规划 分治策略的更多相关文章

  1. [array] leetcode - 53. Maximum Subarray - Easy

    leetcode - 53. Maximum Subarray - Easy descrition Find the contiguous subarray within an array (cont ...

  2. Leetcode#53.Maximum Subarray(最大子序和)

    题目描述 给定一个序列(至少含有 1 个数),从该序列中寻找一个连续的子序列,使得子序列的和最大. 例如,给定序列 [-2,1,-3,4,-1,2,1,-5,4], 连续子序列 [4,-1,2,1] ...

  3. LN : leetcode 53 Maximum Subarray

    lc 53 Maximum Subarray 53 Maximum Subarray Find the contiguous subarray within an array (containing ...

  4. leetcode 53. Maximum Subarray 、152. Maximum Product Subarray

    53. Maximum Subarray 之前的值小于0就不加了.dp[i]表示以i结尾当前的最大和,所以需要用一个变量保存最大值. 动态规划的方法: class Solution { public: ...

  5. 41. leetcode 53. Maximum Subarray

    53. Maximum Subarray Find the contiguous subarray within an array (containing at least one number) w ...

  6. LeetCode 53. Maximum Subarray(最大的子数组)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. leetCode 53.Maximum Subarray (子数组的最大和) 解题思路方法

    Maximum Subarray  Find the contiguous subarray within an array (containing at least one number) whic ...

  8. [LeetCode] 53. Maximum Subarray 最大子数组 --动态规划+分治

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  9. [LeetCode] 53. Maximum Subarray 最大子数组

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

随机推荐

  1. 【题解】洛谷P2822 [NOIP2016TG ]组合数问题 (二维前缀和+组合数)

    洛谷P2822:https://www.luogu.org/problemnew/show/P2822 思路 由于n和m都多达2000 所以暴力肯定是会WA的 因为整个组合数是不会变的 所以我们想到存 ...

  2. c语言描述的简单选择排序

    基本思想:首先,选出最小的数,放在第一个位置:然后,选出第二小的数,放在第二个位置:以此类推,直到所有的数从小到大排序 #include<stdio.h> #include<stdl ...

  3. Struts2 第三讲 -- Struts2的处理流程

    4.Struts2的处理流程 以下是struts-defautl.xml中的拦截器 建议通过这个struts-default的副本查看,更形象 它实现了很多的功能,其中包括国际化,文件上传,类型转换, ...

  4. WebGL学习笔记(3)

    根据上篇笔记,在对3D对象可进行普通的控制后,以及学习了http://hiwebgl.com的教程第10章内容:世界模型的载入以及控制镜头移动,经过多次调试矩阵代码,已经可以实现在世界中旋转镜头/控制 ...

  5. JS 控制文本框禁止输入例子

    JS 控制不能输入特殊字符 <input type="text"class="domain"onkeyup="this.value=this.v ...

  6. fabric Report API

    1.Token生成 接口 : post https://fabric.io/oauth/token 请求头:Headers Content-Type : application/json 正文: bo ...

  7. python 用装饰器写登录

    # 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件), # 要求登录成功一次,后续的函数都无需再输入用户名和密码 # FLAG = False # def login(func): ...

  8. python函数(2017-8-2)

    1. def 函数名(形式参数) 函数体 return "123" 函数执行了return之后就不再执行下面的代码 2. 默认形参实参的位置一一对应 如果要调整位置,指定形参名字 ...

  9. Linux 之vi与vim

    vi 三种模式: 『一般模式』: 光标 『编辑模式』:i,o,a,r 『指令列命令模式』「:/ ?」 例子: 1. 请在/tmp 这个目录下建立一个名为vitest 的目录: 2. 将/etc/man ...

  10. kafka topic 完全删除

    kafka topic 完全删除   1.自动删除脚本(得配置server.properties 中 delete.topic.enable=true) ./kafka-topics.sh --zoo ...