zoukankan      html  css  js  c++  java
  • [leetcode]53. 最大子序和*

    53. 最大子序和

    Difficulty: 简单

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

    示例:

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

    进阶:

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

    Solution 1.0

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            int size = nums.size();
            if(size == 0) return 0;
            vector<int> sum; sum.resize(size);
            sum[0] = nums[0];
            for(int i = 1; i< size; ++i) {
                sum[i] = max(sum[i-1] + nums[i],nums[i]);
            }
            return *max_element(sum.begin(),sum.end());
        }
    };
    

    思路

    遍历当前数组,如果当前位置之前的全部元素和为正值,则算上当前元素结果必然为最大,否则,如果全部元素和为负数,那么以当前元素作为最大值即可。动归的状态转移方程为

    ​ dp[i] = nums[i] + (dp[i-1] > 0?dp[i-1]:0)

    当然,从递推式可以发现,其实并不需要储存全部元素,只需要前后两个元素即可,因此可以缩小空间复杂度。最终,时间复杂度O(n),空间复杂度O(n)。

    Solution 1.1 优化版

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            int size = nums.size();
            if(size == 1) return nums[0];
            int pre = nums[0],cur = nums[1],maximum = nums[0];
            for(int i = 1; i < size;++i){
                cur = nums[i] + (pre >= 0 ? pre : 0);
                maximum = max(cur,maximum);
                pre = cur;
            }
            return maximum;
        }
    };
    

    思路

    减少了空间复杂度。最终,时间复杂度O(n),空间复杂度O(1)。

    *Solution 2 分治法

    思路

    最优解的三种可能:

    1.完全在中间位置的左侧

    2.完全在中间位置的右侧

    3.包含中间位置

  • 相关阅读:
    使用C#实现计划任务(corn job)
    python 修改xml文件
    redis安装
    Nginx的安装
    nginx配置
    用泛型减少重复代码,使代码更合理、更优雅
    Tomcat server.xml配置详解
    二维码生成
    轻量级的中文分词工具包
    HTML解析利器
  • 原文地址:https://www.cnblogs.com/Swetchine/p/13308352.html
Copyright © 2011-2022 走看看