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. vue-element-template模板项目使用记录(持续更新)

    1. npm 使用注意事项: a. node.js 使用 v8.16.0 版本,使用 v10 版本会有各种莫名其妙的报错 b. 开箱先改淘宝镜像: npm config set registry ht ...

  2. windows 使用 virtualbox,搭建 minikube 环境

    win7 virtualbox 版本: 6.0.12 r133076 (Qt5.6.2) centos7:3.10.0-957.27.2.el7.x86_64 1. virtualbox 中创建 ce ...

  3. Nginx 日志切割(Logrotate)

    Logrotate 配置文件 # ls /etc/logrotate.* /etc/logrotate.conf /etc/logrotate.d: cups dracut fmdcn httpd i ...

  4. Java ——方法

    本节重点思维导图  方法的定义 例题:1!+2!+3!+4!+…..+15!=? public class Demo { public static void main(String[] args) ...

  5. 如何统计序列中元素的频度---Python数据结构与算法相关问题与解决技巧

    实际案例: 1. 某随机序列 [12,5,6,4,6,5,5,7]中,找到出现次数最高的3个元素,它们出现的次数是多少? 2. 对于某英文文章的单词,进行词频统计,找到出现次数最高的10个单词,它们出 ...

  6. lesson1-图的概念和图论模型

    说明: 图论专题开设的目的主要是作为本学期复习巩固和分享自己对于图论的理解,主要参考的是老师的PPT.应老师要求,不能共享文件,抱歉! 参考书目:[1] J.A. Bondy,  U.S.R. Mur ...

  7. [Git] 011 checkout 与 reset 命令的补充

    1. git checkout -- <file> 的示意 2. "checkout" 的补充 2.1 git checkout <branch_name> ...

  8. CentOS 下 redis 安装与配置

    CentOS 下 redis 安装与配置   1.到官网上找到合适版本下载解压安装 [root@java src]# wget -c http://redis.googlecode.com/files ...

  9. Django重点之url别名

    django重点之url别名[参数名必须是name,格式是name="XXX] 不论后台路径如何进行修改路径,前台访问的路径不变,永远是alias, 这样方便开发 前台根据 {{ url & ...

  10. HDU 6468 /// DFS

    题目大意: 把 1~15 的数字典序排序后为 1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9 此时给定 n k, 求1~n的数组字典序排序后 第k个 ...