Maximum Subarray(最大子序列和)

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

示例:

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

1.思路:初始化dp[0] = nums[0],dp[i] = max{dp[i] + nums[i] , nums[i]}, max(dp[i])即为所求。但为了节省空间,可使用空间复杂度为O(1)的解法。

时间复杂度O(N),空间复杂度O(1)解法:以maxsum记录当前以nums[i]结尾的最大序列和,并更新总的最大子序列和ans.

    int maxSubArray(vector& nums) {
        int ans = nums[0];
        int maxsum = nums[0];
        for(int i = 1; i < nums.size(); i++){            
            maxsum = maxsum + nums[i] > nums[i] ? maxsum + nums[i] : nums[i];
            ans = maxsum > ans ? maxsum : ans;
        }
        return ans;
    }

2.分治递归。(Divide and Conquer)

最大子序列无非出现在三个位置:左边、右边、中间,于是想到用递归的思路。

    int maxSubArray(vector& nums) {
        return helper(nums,0,nums.size()-1);
    }
    int helper(vector& nums, int left, int right){
        if(left > right)
            return INT32_MIN;
        int mid = (left + right)/2;
        int leftMax = 0,sum = 0;
        for(int i = mid-1; i >= left; i--){
            sum += nums[i];
            leftMax = sum > leftMax ? sum : leftMax;
        }
        int rightMax = 0;
        sum = 0;
        for(int i = mid+1; i <= right; i++){
            sum += nums[i];
            rightMax = sum > rightMax ? sum : rightMax;
        }
        int leftAns = helper(nums,left,mid-1);
        int rightAns = helper(nums,mid+1,right);
        return max(leftMax + rightMax + nums[mid], max(leftAns,rightAns));
    }

 

你可能感兴趣的:(动态规划(dp)算法,校招面试,动态规划(dp)算法)