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.

这道题让求数组中和最大的子数组的和,类似这种“问题的子问题的最优解”问题首先想到的是使用动态规划的方法求解,使用动态规划的难点在于使用适当的dp数组写出问题的正确的状态转移方程,本题的状态转移方程可以表示为:dp[i]=max(dp[i-1]+nums[i],nums[i]),其中dp[i]表示数组中以nums[i]结尾的和最大的子数组的和。这个解法的时间复杂度是 O(n),内存消耗O(n)。代码如下maxSubArray_dp_normal函数所示。由于在计算dp[i]的时候只需要用到dp[i-1],所有可以用一个变量代替dp数组,进行了空间压缩,实现时间复杂度是 O(n),内存消耗O(1),是本题的最优解法,代码如maxSubArray_dp_selected函数所示。

动态规划:


//动态规划 时间O(n) 空间O(n)
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        //return maxSubArray_dp_normal(nums);
        return maxSubArray_dp_seleted(nums);  
    }
    int maxSubArray_dp_normal(vector<int>& nums)
    {
        const int nums_size = nums.size();
        vector<int> dp = nums;//dp[i]表示以nums[i]结尾的和最大的子序列的和
        int res = dp[0];
        for(int i = 1;i<nums_size;++i)
        {
            dp[i] = max(dp[i-1]+nums[i],nums[i]);//状态转移方程 
            res = max(res,dp[i]);
        }
        return res;
    }
    //空间优化了的dp,时间O(n) 空间O(1)
    int maxSubArray_dp_seleted(vector<int> &nums)
    {
        const int nums_size = nums.size();
        int dp = nums[0];
        int res = dp;
        for(int i = 1;i<nums_size;++i)
        {
            dp = max(dp+nums[i],nums[i]);//状态转移方程 
            res = max(res,dp);
        }
        return res;
    } 
};

题目还要求我们用分治法 Divide and Conquer Approach 来解,这个分治法的思想就类似于二分搜索法,需要把数组一分为二,分别找出左边和右边的最大子数组之和,然后还要考虑最大和子数组同时跨越左右两个子数组的情况,具体是从中间开始向左右分别扫描,求出的最大值分别和左右两边得出的最大值相比较取三者最大的那一个,时间复杂度是O(nlogn),显然此种方法不是本题的最优解,分治法代码如下:

分治:


class Solution {
public:
    int maxSubArray(std::vector<int>& nums) {
        int nums_size = nums.size();
        return maxSubArray_div(nums,0,nums_size-1);
    }
    int maxSubArray_div(std::vector<int>& nums,int i,int j)
    {
        if(i>=j) return nums[i];
        int h = (j+i)/2;//也可以使用移位操作
        int left =  maxSubArray_div(nums,i,h);
        int right = maxSubArray_div(nums,h+1,j);
        int mid_value_right = nums[h];
        int r_sum = 0;
        for(int r = h;r<=j;++r)
        {
           r_sum+=nums[r];
           if(r_sum>=mid_value_right) mid_value_right=r_sum;
        }
        int mid_value_left = nums[h];
        int l_sum = 0;
        for(int l = h;l>=i;--l)
        {
            l_sum+=nums[l];
            if(l_sum>=mid_value_left) mid_value_left=l_sum;
        }
        int mid_value = mid_value_left + mid_value_right - nums[h];
        return max(max(left,right),mid_value);
    }  
};
 

[LeetCode] 53. Maximum Subarray 最大子数组 --动态规划+分治的更多相关文章

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

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

  2. [leetcode]53. Maximum Subarray最大子数组和

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

  3. LeetCode 53. Maximum Subarray最大子序和 (C++)

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

  4. 小旭讲解 LeetCode 53. Maximum Subarray 动态规划 分治策略

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

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

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

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

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

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

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

  8. 41. leetcode 53. Maximum Subarray

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

  9. LN : leetcode 53 Maximum Subarray

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

随机推荐

  1. Zipf's law

    w https://www.bing.com/knows/search?q=马太效应&mkt=zh-cn&FORM=BKACAI 马太效应(Matthew Effect),指强者愈强. ...

  2. Django学习之视图

    一.Django的View(视图) 1.一个简单的视图 3.CBV和FBV 4.给视图加装饰器 使用装饰器装饰FBV 使用装饰器装饰CBV 二.Request对象和Response对象 1.reque ...

  3. 用Vue来实现音乐播放器(10):Scroll组件的抽象和应用

    了解better-scroll什么时候是需要refresh计算的??通常我们遇到的better-scroll不能滚动的问题的根源是什么??better-scroll的渲染原理是:根据初始化的时机  或 ...

  4. mysql慢查询解析-linux命令

    使用mysqldumpslow 命令可以解析mysql慢查询日志,mysqldumpslow的参数如下: -s ,是按照任何方式排序,c.t.l.r分别是按照记录次数.时间.查询时间.返回的记录数 来 ...

  5. mysql_存储引擎层-innodb buffer pool

    buffer pool 是innodb存储引擎带的一个缓存池,查询数据时,首先从内存中查询 数据如果内存中存在的话直接返回. innodb buffer pool 和 qcache 的区别:Qcach ...

  6. 红米4高配版 qusb bulk unknow device 不加电,不亮灯,没反应的 黑砖 的维修方法

    unknow device处理 1. 按住按住音量减键和开机键3分钟左右  (我按了10秒左右,就成功了.) unknow device 就变qualcomm hs-usb qdloader 9008 ...

  7. AWS Cloud Practioner 官方课程笔记 - Part 2

    4. AWS Architecture 设计的5个柱子,也就是5大考量点, Security, Reliability, Performance Efficiency, Cost optimizati ...

  8. mooc-IDEA 高效定位代码--004

    十.IntelliJ IDEA -高效定位代码-精准搜索 1.快速定位类:Navigate->Class...   [Ctrl+N] 2.文件:Navigate->File..   [Ct ...

  9. [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)

    [BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...

  10. R语言基础篇——数据读写

    1.键盘输入数据(适合小数据集) #创建一个指定模式但不含数据的变量 mydata<-data.frame(age=numeric(0),gender=character(0),weight=n ...