zoukankan      html  css  js  c++  java
  • LeetCode(53) Maximum Subarray

    题目

    Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

    For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
    the contiguous subarray [4,−1,2,1] has the largest sum = 6.

    click to show more practice.

    More practice:
    If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

    分析

    最大子序列和的问题,这道题我写出的是O(n)的算法,属于简单的动态规划,根据题目后面的more practice说明该题目还有更优的分治法解决思路。

    AC代码-动态规划

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
    
            if (nums.empty())
                return 0;
    
            //求数组的长度
            int len = nums.size();
    
            //将最大和赋值为首元素值,temp记录临时子序列和
            int maxSum = nums[0], temp = 0;
            for (int i = 0; i < len; i++)
            {
                temp += nums[i];
    
                //若元素和大于当前最大和
                if(temp > maxSum)
                {
                    maxSum = temp;
                }//else
    
                //若子系列和为非正数,则从下一个元素重新记录
                if (temp <= 0)
                {
                    temp = 0;
                }
    
            }//for
    
            return maxSum;
        }
    };
    

    AC代码-分治法

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
    
            if (nums.empty())
                return 0;
    
            //求数组的长度
            int len = nums.size();
    
            return Divide(nums , 0 , len-1);
        }
    
        //分治法
        int Divide(const vector<int> &nums, int lhs, int rhs)
        {
            if (lhs == rhs)
                return nums[lhs];
    
            int mid = (lhs + rhs) / 2;
            int leftMaxSum = Divide(nums, lhs, mid);
            int rightMaxSum = Divide(nums, mid + 1, rhs);
    
            int lsum = INT_MIN;
            int rsum = INT_MIN;
    
            int temp = 0;
            for (int i = mid; i >= lhs; i--)
            {
                temp += nums[i];
                if (temp > lsum)
                    lsum = temp;
            }
    
            temp = 0;
            for (int i = mid + 1; i <= rhs; i++)
            {
                temp += nums[i];
                if (temp > rsum)
                    rsum = temp;
            }
    
            //跨越中点的最大子序列和
            temp = lsum + rsum;
    
            return std::max(temp, std::max(leftMaxSum, rightMaxSum));
        }
    };

    GitHub测试程序源码

  • 相关阅读:
    算法经典文章收藏
    Python 学习文章收藏
    Leetcode 刷题计划
    CLR via C# 学习计划
    算法导论 学习计划
    算法导论学习笔记 一 分治算法
    Mongodb 学习笔记
    Python模拟HttpRequest的方法总结
    在Github上搭建自己的博客(Windows平台)
    Git Shell 基本命令(官网脱水版)
  • 原文地址:https://www.cnblogs.com/shine-yr/p/5214882.html
Copyright © 2011-2022 走看看