zoukankan      html  css  js  c++  java
  • 53. Maximum Subarray (Array; DP)

    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.

    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.

    法I:动态规划。max_local存储到i之前的sum,如果<0,表示之前的sum对之后只可能有负贡献,所以忽略,直接考虑nums[i]。max_global存储目前为止出现过的最大sum。

    动态转移方程是:

    局部最优:max_local= max(max_local+nums[i], nums[i])

    全局最优:max_global= max(max_global, max_local)

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            int max_local = nums[0];  //maxSum may be negative, so can't simply write int curSum = 0
            int max_global = nums[0];
            for(int i = 1; i < nums.size(); i++){
                max_local = max(max_local+nums[i],nums[i]);
                max_global = max(max_global, max_local);
            }
            return max_global;
        }
    };

    法II:分治法

    将数组分为左右两段,分别找到最大子串和,然后还要从中间开始往两边扫描,求出最大和,比较三个和取最大值。

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            return binarySearch(nums,0,nums.size()-1);
        }
        
        int binarySearch(vector<int>& nums, int left, int right){
            //right=left<=1的两种情况都要讨论
            if(left==right)
                return nums[left];
            if(right-left == 1){
                return max(max(nums[left],nums[right]),nums[left]+nums[right]);
            }
            
            int mid = left +((right-left)>>1);
            int leftmax = binarySearch(nums, left, mid);
            int rightmax = binarySearch(nums, mid+1, right);
            
            int curLeft = nums[mid],curRight=nums[mid+1], maxLeft=nums[mid], maxRight=nums[mid+1];
            for(int i = mid-1; i>=left; i--){
                curLeft+=nums[i];
                maxLeft = max(curLeft,maxLeft);
            }
            for(int i = mid+2; i <= right; i++){
                curRight+=nums[i];
                maxRight = max(curRight,maxRight);
            }
            
            return max(max(leftmax,rightmax),maxLeft+maxRight);
        }
    };
  • 相关阅读:
    C# delegate委托的用法
    C# new关键字的使用
    C# abstract抽象类的使用
    C# override关键字的使用
    C# sealed关键字的使用
    C# 虚函数virtual的使用
    Java IO流简介
    SpringBoot中异步请求的使用
    SpringBoot中异步调用的使用
    github
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/4857251.html
Copyright © 2011-2022 走看看