• 连续数列


    给定一个整数数组(有正数有负数),找出总和最大的连续数列,并返回总和。

    示例:

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

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

    code:

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            if(nums.empty())
                return 0;
            
            int len=nums.size();
            int sum=nums[0],tmpSum=nums[0];
            for(int i=1;i<len;++i)
            {
                if(tmpSum<0)
                    tmpSum=nums[i];
                else
                    tmpSum+=nums[i];
                sum=max(sum,tmpSum);
            }
            return sum;
        }
    };

     code2:动态规划

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            if(nums.empty())
                return 0;
    
            int len=nums.size();
            vector<int> dp(len);//dp[i]=从左到右,包含以i结尾的子数组的最大和
            dp[0]=nums[0];
            int sum=nums[0];
            for(int i=1;i<len;++i)
            {
                dp[i]=max(nums[i]+dp[i-1],nums[i]);
                sum=max(dp[i],sum);
            }
            return sum;
        }
    };

     code3:归并,把整体数组看做两部分:左半部分和右半部分,那么最大子数组和可能出现的情况有三种:

    1. 左半部分
    2. 右半部分
    3. 同时包含左半部分和右半部分
    class Solution {
    private:
        int merge(const vector<int>& nums,int left,int right)
        {
            if(right-left==1)
                return nums[left];
            
            int mid=left+((right-left)>>1);//1.最大和包含在左半部分。mid元素属于右半部分
            int maxLeft=merge(nums,left,mid);//2.最大和包含在右半部分。不用mid-1,因为不包含右边界
            int maxRight=merge(nums,mid,right);
            
            int tmp=0,maxLeftSub=nums[mid-1];//3.最大和可能出现的位置是同时包含左半部分和右半部分的情况
            for(int i=mid-1;i>=left;--i)
            {
                tmp+=nums[i];
                maxLeftSub=max(maxLeftSub,tmp);
            }
            int maxrightSub=nums[mid];
            tmp=0;
            for(int i=mid;i<right;++i)
            {
                tmp+=nums[i];
                maxrightSub=max(maxrightSub,tmp);
            }
    
            return max(max(maxLeft,maxRight),maxLeftSub+maxrightSub);
        }
    public:
        int maxSubArray(vector<int>& nums) {
            if(nums.empty())
                return 0;
            
            return merge(nums,0,nums.size());
        }
    };
  • 相关阅读:
    如何通过转换例程加减前导0
    PA教材提纲 TAW12-2
    Web开发框架趋势
    ASP.NET MVC
    一步步实现Promise
    在Jenkins中使用Git Plugin访问Https代码库失败的问题
    5年从DBA到运维架构总监 — 做对了什么
    Hello又大了一岁
    JavaWeb限流QPS简易框架
    JAVA异常使用_每个人都曾用过、但未必都用得好
  • 原文地址:https://www.cnblogs.com/tianzeng/p/12323258.html
Copyright © 2020-2023  润新知