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. AtomicInteger 源码分析

    AtomicInteger AtomicInteger 能解决什么问题?什么时候使用 AtomicInteger? 支持原子更新的 int 值. 如何使用 AtomicInteger? 1)需要被多线 ...

  2. 【转】一个 Vim 重度用户总结的 vim 超全指南

    [转]一个 Vim 重度用户总结的 vim 超全指南 我本人是 Vim 的重度使用者,就因为喜欢上这种双手不离键盘就可以操控一切的feel,Vim 可以让我对文本的操作更加精准.高效. 对于未使用过 ...

  3. 包管理器 - peer dependency 的安装

    npm 和 yarn 安装依赖(包)时不会自动安装 peer dependence(虽然很旧的 npm 是会自动安装的,但几乎没人用那么旧的了),而是给出如下警告: $ npm install --s ...

  4. python使用__new__创建一个单例模式(单例对象)

    #单例模式:使一个类只产生一个对象.他们的id地址都指向同一个内存地址 第一步:理解谁创建了对象 # 单例模式# 首先明白,我们在创建一个类的对象的时候,其实是调用的这个类的父类,即继承object, ...

  5. python 操作openpyxl导出Excel 设置单元格格式以及合并处理

    贴上一个例子,里面设计很多用法,根据将相同日期的某些行合并处理. from openpyxl import Workbook from openpyxl.styles import Font, Fil ...

  6. centos7下搭建Testlink环境详细过程

    花了半天的时间终于搭建好了完整的Testlink环境,主要包括Mysql以及PHP的版本.未关闭防火墙.以及安装配置过程中遇到的一些问题.以下是详细的搭建过程. 一.工具准备 以下是我在搭建过程中用到 ...

  7. 单调栈 && 洛谷 P2866 [USACO06NOV]糟糕的一天Bad Hair Day(单调栈)

    传送门 这是一道典型的单调栈. 题意理解 先来理解一下题意(原文翻译得有点问题). 其实就是求对于序列中的每一个数i,求出i到它右边第一个大于i的数之间的数字个数c[i].最后求出和. 首先可以暴力求 ...

  8. Appium+Python之异常自动截图

    运行过程中出现异常情况,我们怎么直观的看到呢?最简单的方法就是可以把异常现象截图下来. 思路:我这里采用get_screenshot_as_file(filename)方法,filename通过获取时 ...

  9. 字典树(Trie树)实现与应用(转)

    一.概述 1.基本概念 字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种. 2.基本性质 根节点不包含字符,除根节点外的每一个子节点都包含一个字符 从根节点到某一节点.路径上 ...

  10. javascript中无法将string转化为json对象

    在一次项目之中,我要对请求的相应做一些处理,得到的响应差不多是这中格式'{total:1,result:[{"age":1}]}'.可以看到我拿到的这个相应和JSON的格式是非常相 ...