1. 程式人生 > 實用技巧 >劍指 Offer 42. 連續子陣列的最大和(動態規劃)

劍指 Offer 42. 連續子陣列的最大和(動態規劃)

https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/

1、題目描述:

  輸入一個整型陣列,數組裡有正數也有負數。陣列中的一個或連續多個整陣列成一個子陣列。求所有子陣列的和的最大值。

  要求時間複雜度為O(n)。

2、示例1:

輸入: nums = [-2,1,-3,4,-1,2,1,-5,4]

輸出: 6

解釋:連續子陣列[4,-1,2,1] 的和最大,為6。

3、思路:

(1)定義狀態:

假設 dp(i) 是以 nums[i] 結尾的最大連續子序列和(nums是整個序列)

✓以 nums[0] –2 結尾的最大連續子序列是 –2,所以 dp(0) = –2

✓ 以 nums[1] 1 結尾的最大連續子序列是 1,所以 dp(1) = 1
✓ 以 nums[2] –3 結尾的最大連續子序列是 1、–3,所以 dp(2) = dp(1) + (–3) = –2
✓ 以 nums[3] 4 結尾的最大連續子序列是 4,所以 dp(3) = 4
✓ 以 nums[4] –1 結尾的最大連續子序列是 4、–1,所以 dp(4) = dp(3) + (–1) = 3
✓ 以 nums[5] 2 結尾的最大連續子序列是 4、–1、2,所以 dp(5) = dp(4) + 2 = 5
✓ 以 nums[6] 1 結尾的最大連續子序列是 4、–1、2、1,所以 dp(6) = dp(5) + 1 = 6
✓ 以 nums[7] –5 結尾的最大連續子序列是 4、–1、2、1、–5,所以 dp(7) = dp(6) + (–5) = 1
✓ 以 nums[8] 4 結尾的最大連續子序列是 4、–1、2、1、–5、4,所以 dp(8) = dp(7) + 4 = 5

(2)狀態轉移方程:

如果 dp(i – 1) ≤ 0,那麼 dp(i) = nums[i]
如果 dp(i – 1) > 0,那麼 dp(i) = dp(i – 1) + nums[i]

(3)初始狀態:

dp(0) 的值是 nums[0]

(4)最終的解:

最大連續子序列和是所有 dp(i) 中的最大值 max { dp(i) },i ∈ [0, nums.length)

4、程式碼:

class Solution {
    public int maxSubArray(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        int max = dp[0];
        for (int i = 1; i < nums.length; i++) {
            if (dp[i - 1] < 0) {
                dp[i] = nums[i];
            } else {
                dp[i] = dp[i - 1] + nums[i];
            }
            max = Math.max(dp[i], max);
        }
        return max;
    }
}