当前位置: 首页 > news >正文

用dw做网站的教程哈尔滨seo关键词

用dw做网站的教程,哈尔滨seo关键词,wordpress 批量,学习网站推荐【LetMeFly】53.最大子数组和:DP 或 递归 力扣题目链接:https://leetcode.cn/problems/maximum-subarray/ 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最…

【LetMeFly】53.最大子数组和:DP 或 递归

力扣题目链接:https://leetcode.cn/problems/maximum-subarray/

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

 

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

 

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

 

进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

方法一:DP

使用动态规划的话思路比较简单,使用一个变量 c n t cnt cnt记录以当前元素为结尾的最大子数组和

这样,我们只需要遍历一遍 n u m s nums nums数组,使用公式 c n t = max ⁡ ( c n t + n u m s [ i ] , n u m s [ i ] ) cnt = \max(cnt + nums[i], nums[i]) cnt=max(cnt+nums[i],nums[i])维护 c n t cnt cnt,并记得更新答案的最大值即可。

  • 时间复杂度 O ( l e n ( n u m s ) ) O(len(nums)) O(len(nums))
  • 空间复杂度 O ( 1 ) O(1) O(1)

AC代码

C++
class Solution {
public:int maxSubArray(vector<int>& nums) {int ans = nums[0];int cnt = nums[0];for (int i = 1; i < nums.size(); i++) {cnt = max(cnt + nums[i], nums[i]);ans = max(ans, cnt);}return ans;}
};
Python
# from typing import Listclass Solution:def maxSubArray(self, nums: List[int]) -> int:ans, cnt = nums[0], nums[0]for i in range(1, len(nums)):cnt = max(cnt + nums[i], nums[i])ans = max(ans, cnt)return ans

方法二:递归(分治)

写一个函数 g e t ( n u m s , l , r ) get(nums, l, r) get(nums,l,r),返回 n u m s nums nums数组从 l l l r r r的子数组的:

  1. lSum: 以 n u m s [ l ] nums[l] nums[l]为起点的最大子数组和
  2. rSum: 以 n u m s [ r ] nums[r] nums[r]为终点的最大子数组和
  3. MSum: 最大子数组和
  4. iSum: 和

那么,我们就可以愉快地进行递归啦!

对于 g e t ( n u m s , l , r ) get(nums, l, r) get(nums,l,r),我们可以分别求出 g e t ( n u m s , l , ⌊ l + r 2 ⌋ ) get(nums, l, \lfloor\frac{l + r}{2}\rfloor) get(nums,l,2l+r⌋)(记为 l S t a t u s lStatus lStatus)和 g e t ( n u m s , ⌊ l + r 2 ⌋ + 1 , r ) get(nums, \lfloor\frac{l + r}{2}\rfloor + 1, r) get(nums,2l+r+1,r)(记为 r S t a t u s rStatus rStatus)。递归终止条件为 l = r l=r l=r(只有单个元素)。

于是就有:

  1. l S u m = max ⁡ ( l S t a t u s . l S u m , l S t a t u s . i S u m + r S t a t u s . l S u m ) lSum = \max(lStatus.lSum, lStatus.iSum + rStatus.lSum) lSum=max(lStatus.lSum,lStatus.iSum+rStatus.lSum)(以 n u m s [ l ] nums[l] nums[l]为起点,不跨过 n u m s [ ⌊ l + r 2 ⌋ ] nums[\lfloor\frac{l + r}{2}\rfloor] nums[⌊2l+r⌋]和跨过)
  2. r S u m = max ⁡ ( r S t a t u s . r S u m , l S t a t u s . r S u m + r S t a t u s . i S u m ) rSum = \max(rStatus.rSum, lStatus.rSum + rStatus.iSum) rSum=max(rStatus.rSum,lStatus.rSum+rStatus.iSum)(以 n u m s [ r ] nums[r] nums[r]为终点,不跨过 n u m s [ ⌊ l + r 2 ⌋ ] nums[\lfloor\frac{l + r}{2}\rfloor] nums[⌊2l+r⌋]和跨过)
  3. M S u m = max ⁡ ( l S t a t u s . M S u m , r S t a t u s . M S u m , l S t a t u s . r S u m + r S t a t u s . l S u m ) MSum = \max(lStatus.MSum, rStatus.MSum, lStatus.rSum + rStatus.lSum) MSum=max(lStatus.MSum,rStatus.MSum,lStatus.rSum+rStatus.lSum)(左半部分最大子数组和、右半部分最大子数组和、跨过 n u m s [ ⌊ l + r 2 ⌋ ] nums[\lfloor\frac{l + r}{2}\rfloor] nums[⌊2l+r⌋]的子数组和)
  4. i S u m = l S t a t u s . i S u m + r S t a t u s . i S u m iSum = lStatus.iSum + rStatus.iSum iSum=lStatus.iSum+rStatus.iSum(左半右半数组和 之和)

最终返回 g e t ( n u m s , 0 , l e n ( n u m s ) − 1 ) . M S u m get(nums, 0, len(nums) - 1).MSum get(nums,0,len(nums)1).MSum即可。

  • 时间复杂度 O ( l e n ( n u m s ) ) O(len(nums)) O(len(nums))(相当于后序遍历了一遍二叉树)
  • 空间复杂度 O ( log ⁡ l e n ( n u m s ) ) O(\log len(nums)) O(loglen(nums))(空间复杂度主要来源于递归)

AC代码

C++
struct Status {int lSum, rSum, MSum, iSum;
};class Solution {
private:Status get(vector<int>& a, int l, int r) {  // get[l, r]if (l == r) {return {a[l], a[l], a[l], a[l]};}int m = (l + r) >> 1;Status lStatus = get(a, l, m);Status rStatus = get(a, m + 1, r);return {max(lStatus.lSum, lStatus.iSum + rStatus.lSum),max(rStatus.rSum, lStatus.rSum + rStatus.iSum),max(lStatus.MSum, max(rStatus.MSum, lStatus.rSum + rStatus.lSum)),lStatus.iSum + rStatus.iSum};}
public:int maxSubArray(vector<int>& nums) {return get(nums, 0, nums.size() - 1).MSum;}
};
Python
# from typing import Listclass Status:def __init__(self, lSum: int, rSum: int, MSum: int, iSum: int) -> None:self.lSum = lSumself.rSum = rSumself.MSum = MSumself.iSum = iSumclass Solution:def get(self, nums: List[int], l: int, r: int) -> Status:if l == r:return Status(nums[l], nums[l], nums[l], nums[l])m = (l + r) >> 1lStatus = self.get(nums, l, m)rStatus = self.get(nums, m + 1, r)return Status(max(lStatus.lSum, lStatus.iSum + rStatus.lSum),max(rStatus.rSum, lStatus.rSum + rStatus.iSum),max(lStatus.MSum, rStatus.MSum, lStatus.rSum + rStatus.lSum),lStatus.iSum + rStatus.iSum)def maxSubArray(self, nums: List[int]) -> int:return self.get(nums, 0, len(nums) - 1).MSum"""为何不用切片作为参数?
>>> a = [1, 2, 3]
>>> a
[1, 2, 3]
>>> b = a[1:2]
>>> b
[2]
>>> b[0] = 99
>>> a
[1, 2, 3]
>>> b
[99]
"""

方法二意义何在?

相较于方法一,方法二的时间复杂度没有提升,空间复杂度反而更高了。那么方法二的意义何在?

这道题只问了“整个数组的”最大子数组和。但是如果某天遇到了一道题,问你 1 0 5 10^5 105次且每次随机问一个 [ l , r ] [l, r] [l,r]的最大子数组和 呢?

那么我们使用方法二,并且将每层的结果记录下来,就能做到每次查询都在 O ( log ⁡ n ) O(\log n) O(logn)的时间复杂度下返回结果。

这就是没有懒标记的线段树。

同步发文于CSDN,原创不易,转载经作者同意后请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/134504375

http://www.hengruixuexiao.com/news/15024.html

相关文章:

  • 做外账经常进哪几个网站个人怎么做百度竞价
  • 安徽做网站电话代发新闻稿最大平台
  • wordpress主题jquery杭州百度整站优化服务
  • 给你网站你会怎么做的网络运营工作内容
  • 备案的网站 能拿来做仿站吗网站建设对企业品牌价值提升的影响
  • 莱芜二中网站b站怎么推广
  • 做前端网站用什么工具郑州seo外包顾问
  • 开发公司未售房产交的取暖费应走什么科目搜索seo怎么优化
  • 长沙哪家做网站设计好营销咨询公司排名前十
  • 犀牛云 做网站seo培训讲师招聘
  • 做公司网站优劣势网站建立
  • 5个网站建设希爱力双效片
  • 昭通网站制作怎么在百度做广告
  • wap网站建设兴田德润实惠如何提高关键词搜索排名
  • 网页制作三剑客是指哪三个软件长尾词排名优化软件
  • 广州市建设厅网站青青河边草直播免费观看
  • 做一个网站大概要多少钱seo01网站
  • wordpress anti ccseo扣费系统
  • 做百度翻译英文网站百度关键词搜索技巧
  • 做网站的硬件和软件环境目前最新的营销模式有哪些
  • 新建网站二级网页怎么做深圳推广公司介绍
  • php动态网站开发教程搜狗站长
  • 天津做网站多少钱全国教育培训机构平台
  • 你们网站做301武汉网络营销推广
  • 新疆建设兵团125团网站市场营销策略包括哪些策略
  • 提供商城网站建设百度推广登录入口官网网址
  • 做招聘网站还有法盈利吗网站推广优化怎么做最好
  • 上海最新风险地区一览表pc优化工具
  • idc销售网站模板成都搜狗seo
  • 保定网站建设公司微信公众平台开发