zoukankan      html  css  js  c++  java
  • 53. Maximum Subarray

    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的方法解决。

    当我们确定用DP的方法解决时,就需要确定此问题的子问题是什么。此题的子问题可以定为 maxSubArray(vector<int> &nums, int i); 就是在子序列nums[0:i] 中的最大序列。

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            int n = nums.size();
            if (n == 1) return nums[0];
           // if (n == 2) return max(nums[0],nums[1]);
            vector<int> dp(n);
            dp[0] = nums[0];
            int maxSum = dp[0];
            for (int i = 1; i < n; ++i)
            {
                dp[i] = dp[i - 1] > 0?(dp[i - 1] + nums[i]):nums[i];
                maxSum = max(maxSum,dp[i]);
            }
            return maxSum;
        }
    };

    优质解:Divide and Conquer(分治思想)

    待学习。。。。。。

    1) Divide the given array in two halves
    2) Return the maximum of following three
    ….a) Maximum subarray sum in left half (Make a recursive call)
    ….b) Maximum subarray sum in right half (Make a recursive call)
    ….c) Maximum subarray sum such that the subarray crosses the midpoint

    The lines 2.a and 2.b are simple recursive calls. How to find maximum subarray sum such that the subarray crosses the midpoint? We can easily find the crossing sum in linear time. The idea is simple, find the maximum sum starting from mid point and ending at some point on left of mid, then find the maximum sum starting from mid + 1 and ending with sum point on right of mid + 1. Finally, combine the two and return.

    // A Divide and Conquer based program for maximum subarray sum problem 
    #include <stdio.h> 
    #include <limits.h> 
    
    // A utility funtion to find maximum of two integers 
    int max(int a, int b) { return (a > b)? a : b; } 
    
    // A utility funtion to find maximum of three integers 
    int max(int a, int b, int c) { return max(max(a, b), c); } 
    
    // Find the maximum possible sum in arr[] auch that arr[m] is part of it 
    int maxCrossingSum(int arr[], int l, int m, int h) 
    { 
        // Include elements on left of mid. 
        int sum = 0; 
        int left_sum = INT_MIN; 
        for (int i = m; i >= l; i--) 
        { 
            sum = sum + arr[i]; 
            if (sum > left_sum) 
            left_sum = sum; 
        } 
    
        // Include elements on right of mid 
        sum = 0; 
        int right_sum = INT_MIN; 
        for (int i = m+1; i <= h; i++) 
        { 
            sum = sum + arr[i]; 
            if (sum > right_sum) 
            right_sum = sum; 
        } 
    
        // Return sum of elements on left and right of mid 
        return left_sum + right_sum; 
    } 
    
    // Returns sum of maxium sum subarray in aa[l..h] 
    int maxSubArraySum(int arr[], int l, int h) 
    { 
    // Base Case: Only one element 
    if (l == h) 
        return arr[l]; 
    
    // Find middle point 
    int m = (l + h)/2; 
    
    /* Return maximum of following three possible cases 
        a) Maximum subarray sum in left half 
        b) Maximum subarray sum in right half 
        c) Maximum subarray sum such that the subarray crosses the midpoint */
    return max(maxSubArraySum(arr, l, m), 
                maxSubArraySum(arr, m+1, h), 
                maxCrossingSum(arr, l, m, h)); 
    } 
    
    /*Driver program to test maxSubArraySum*/
    int main() 
    { 
    int arr[] = {2, 3, 4, 5, 7}; 
    int n = sizeof(arr)/sizeof(arr[0]); 
    int max_sum = maxSubArraySum(arr, 0, n-1); 
    printf("Maximum contiguous sum is %dn", max_sum); 
    getchar(); 
    return 0; 
    } 
  • 相关阅读:
    linux源码解读(五):文件系统——文件和目录的操作
    linux源码解读(二):文件系统——高速缓存区
    linux源码解读(一):进程的创建、调度和销毁
    linux源码解读(四):文件系统——挂载和卸载
    .net工作室第六周、类。人打怪兽
    无法将类型为“System.Web.UI.LiteralControl”的对象强制转换为类型
    sql查询语句
    .net工作室第七周 数据库
    时间函数的使用。
    GridView 删除数据
  • 原文地址:https://www.cnblogs.com/qiang-wei/p/11939903.html
Copyright © 2011-2022 走看看