剑指offe 42 连续子树组中的最大和
题目描述
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).
示例1
输入:[1,-2,3,10,-4,7,2,-5]
返回值:18
说明:输入的数组为{1,-2,3,10,—4,7,2,一5},和最大的子数组为{3,10,一4,7,2},因此输出为该子数组的和 18。
思路
- 看到求最大前n项和。最直接的最暴力的方法就是遍历全部子数组和并且一一比较大小。显然这样做回导致复杂度为O(n2)O(n^2)O(n2)。
- 根据陈越老师的思想方法——看到O(n2)O(n^2)O(n2)可以尝试转换到O(nlogn)O(nlogn)O(nlogn)。但是题目已经要求复杂度为O(n)。
- O(n)O(n)O(n)就可以看出这道题只能遍历(for循环)一次数组。
- 思考最极限状况。极限状态1:数组元素全为正整数——[4,5,2,6,8,1],最大子数组和就是数组本身元素和。极限状态2:数组元素全为负数——[-3,-7,-1-9,-10],最大子数和为-1,是数组元素。
- 普通状态:数组有负有正——[1,-2,3,10,-4,7,2,-5]。在人为计算最大子数和时,发现只要是前面子数和一旦为负数,只要是包含这个子数组全部元素必然不是最大的子树和,需要抛弃掉为负数的子树和。
class Solution {public:int FindGreatestSumOfSubArray(vector<int> array) {int sum, tmp;sum = INT32_MIN; // 子数和可以为负数,所以初始化为int型最小值tmp = 0;for(int i = 0; i < array.size(); ++i){tmp += array[i];if(tmp > sum)sum = tmp;if(tmp < 0) // 一旦发现前面的子数组和为负数,//就会影响到下一次的累加(但不影响此次,所以需要把判断放在最后)。tmp = 0;}return sum;}
};
上述我这个使用了判断结构,下面这段代码更加简洁,一样的思想。不过是使用max函数替代了判断,如果是自己写完整代码记得一定要加头文件#include<algorithm>
。下面代码出自这。
class Solution {public:int maxSubArray(vector<int>& nums) {int resmax = INT_MIN, curmax = 0;//resmax表示整个数组的最大连续子数组和,curmax表示当前最大连续子数组和for (int i = 0; i < nums.size(); ++i) {curmax += nums[i];resmax = max(resmax, curmax);//更新结果curmax = max(curmax, 0);//如果目前<0,说明拖后腿,就丢了}return resmax;}
};
应用动态规划方式:如果用函数f(i)f(i)f(i)表示以第iii个数字结尾的子数组的最大和(可正可负),那么就可以利用递归公式:f(n)={Data[i],if i=0or f(i−1)≤0f(i−1)+Data[i],if i≠0and f(i−1)>0f(n) = \begin{cases} Data[i], & \text{if $i = 0$ or $f(i-1) \leq 0$} \\ f(i-1) + Data[i], & \text{if $i \neq 0$ and $f(i-1) > 0$} \end{cases} f(n)={Data[i],f(i−1)+Data[i],if i=0 or f(i−1)≤0if i=0 and f(i−1)>0
class Solution {public:int FindGreatestSumOfSubArray(vector<int> array) {// 动态规划方法:if(array.size() == 0)return 0;vector<int> f(array.size(),0);// i = 0f[0] = array[0];int MaxValue = f[0];// i 不等于 0 for(int i = 1; i < array.size(); ++i){f[i] = max(f[i-1] + array[i], array[i]);MaxValue = max(MaxValue, f[i]);}return MaxValue;}
};
但是可以避免使用vector容器,以及不需要分iii是否是等于0。代码出自这。
class Solution {public:int maxSubArray(vector<int>& nums) {int res = INT_MIN, s = 0;//res是结果,s是以前一个数结尾的所有子数组中的最大和for (int i = 0; i < nums.size(); ++i) {s = max(s + nums[i], nums[i]);//以当前i结尾的所有子数组的最大和:若s > 0,则s+nums[i]最大,若s<=0,则丢掉前面的最大;res = max(res, s);}return res;}
};
剑指offe 42 连续子树组中的最大和相关推荐
- 【LeetCode】剑指 Offer 42. 连续子数组的最大和
[LeetCode]剑指 Offer 42. 连续子数组的最大和 文章目录 [LeetCode]剑指 Offer 42. 连续子数组的最大和 一.动态规划 一.动态规划 状态定义 设动态规划列表 dp ...
- 剑指 Offer 42. 连续子数组的最大和(官解)
14天阅读挑战赛 努力是为了不平庸~ 算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!欢迎记录下你的那些努力时刻(算法学习知识点/算法题解/遇到的算法bug/等等),在分享的同时加深对于算 ...
- 剑指 Offer 42. 连续子数组的最大和
摘要 剑指 Offer 42. 连续子数组的最大和 一. 动态规划分析 1.1 动态规划思路分析 假设nums数组的长度是n,下标从0到n−1.我们用 f(i)代表以第i个数结尾的连续子数组的最大和, ...
- LeetCode -- 剑指 Offer 42. 连续子数组的最大和
剑指 Offer 42. 连续子数组的最大和 线性 DP 题. 针对于数组nums[i] 而言,以它为结尾的子数组分两种情况:(题目限制:必须是连续数组) num[i] 自身作为独立子数组:f[i] ...
- Leetcode 剑指 Offer 42. 连续子数组的最大和 (每日一题 20211014)
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值.要求时间复杂度为O(n).示例1:输入: nums = [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 ...
- 【最佳解法】剑指 Offer 42. 连续子数组的最大和
我是小张同学,立志用最简洁的代码做最高效的表达 思路:动态规划 假设nums\textit{nums}nums 数组的长度是 nnn,下标从 000 到 n−1n-1n−1. 我们用 f(i)f(i) ...
- leetcode剑指 Offer 42. 连续子数组的最大和(动态规划)
输入一个整型数组,数组里有正数也有负数.数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值. 要求时间复杂度为O(n). 示例1: 输入: nums = [-2,1,-3,4,-1,2 ...
- 剑指 Offer 42. 连续子数组的最大和java
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值. 要求时间复杂度为O(n). 示例1: 输入: nums = [-2,1,-3,4,-1,2,1,-5,4] 输出 ...
- 【算法】剑指 Offer 42. 连续子数组的最大和 【重刷】
1.概述 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值. 要求时间复杂度为O(n). 示例1: 输入: nums = [-2,1,-3,4,-1,<
最新文章
- 利用java多线程向MongoDB中批量插入静态文件
- 把JS 脚本嵌入CS运行
- [Usaco2008 Oct]灌水
- ubuntu 打开ssh登陆_Ubuntu 开启远程登录 SSH 的安装和配置
- 前端攻略系列(二) - 前端各种面试题
- [Bug]Object reference not set to an instance of an object.
- swing 选择对话框_Java Swing –日期选择器对话框
- Mutex和内存可见性
- 一步教你轻松实现--Word方括号打勾☑
- 从零开始学WEB前端——网页的骨架——HTML实战练习
- JS 的5个不良编码习惯,现在就改掉吧
- 最新微博图片相册批量下载工具
- 配置postfix邮件监控
- Centos7上的Ansible管理Windows主机的部署
- 1705. 吃苹果的最大数目(贪心、优先队列(堆)、哈希表),总之先吃快烂的苹果
- AndroidStudio连接第三方模拟器的简易方法
- python短网址转换
- 数据库、数据库管理系统和数据库系统的区别
- HDOJ中的a+b问题汇总
- 自定义加载更多的Recycleview