【LeetCode】53.最大子序和

最大子序和

給定一個整數數組 nums ,找到一個具備最大和的連續子數組(子數組最少包含一個元素),返回其最大和。
示例:java

輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。
---數組

動態規劃

分析

1.首先對數組進行遍歷,當前最大連續子序列和爲sum,結果爲ans;
2.若是sum > 0,則說明sum對最終結果有增益,則保留並加上當前遍歷的元素;
3.若是sum <= 0,則說明sum無增益,需捨棄,從新更新爲當前遍歷的元素;
4.每次比較sum和ans的大小,將最大值置爲ans,循環結束返回ans;code

class Solution {
    public int maxSubArray(int[] nums) {
        int ans = nums[0];
        int sum = 0;
        for(int num: nums) {
            if(sum > 0) {
                sum += num;
            } else {
                sum = num;
            }
            ans = Math.max(ans, sum);
        }
        return ans;
    }
}

分治法

分析

將數組一分爲二,那麼最大子序和出現的位置有三種狀況,1.左邊,2.右邊,3.橫跨中間。其中左右兩邊的狀況能夠遞歸處理,最後返回三種狀況的最大值。遞歸

class Solution {
    public int maxSubArray(int[] nums) {
        return __maxSubArray(nums, 0, nums.length - 1);
    }
    
    static int __maxSubArray(int[] nums, int start, int end){
        
        if(start == end)
            return nums[start];
        
        if(start > end)
            return Integer.MIN_VALUE;

        int mid = (start + end) / 2;
        //遞歸計算左半邊最大子序和
        int max_left = __maxSubArray(nums, start, mid - 1);
        //遞歸計算右半邊最大子序和
        int max_right = __maxSubArray(nums, mid + 1, end);
        
        //計算中間最大子序和
        int max_mid = nums[mid];
        int sum = nums[mid];
        for(int i = mid - 1; i >= start; i--){
            sum += nums[i];
            max_mid = Math.max(sum, max_mid);
        }
        sum = max_mid;
        for(int i = mid + 1; i <= end; i++){
            sum += nums[i];
            max_mid = Math.max(sum, max_mid);
        }
        
        //返回三種狀況中的最大值
        return Math.max(Math.max(max_left, max_right), max_mid);
    }
}
相關文章
相關標籤/搜索