---
# System prepended metadata

title: 53. Maximum Subarray

---

# 53. Maximum Subarray

## 題目概要
在 nums 整數陣列中找出總和最大的連續子陣列(最少要有一個元素)，並返回最大值。

```
Example 1:
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Example 2:
Input: nums = [1]
Output: 1

Example 3:
Input: nums = [5,4,-1,7,8]
Output: 23
```

## 解題技巧
- 可以使用貪婪演算法(Greedy algorithm)或動態規劃(Dynamic programming)來解。


## 程式碼

### 貪婪演算法

用 for 循環遍歷一個一個元素慢慢往下加，然後將總和跟當前最大值比較，將比較大的值存下來。一旦當前的數小於 0 的時候就將當前總和歸零，繼續找下一個子陣列。

PS. 注意 max 一定要預設為 -Infinity，因為總和會有負數，如果設為 0 會是錯的。

```javascript=
var maxSubArray = function(nums) {
    let max = -Infinity; // 當前最大子序列的總和
    let sum = 0; // 當前總和
    for(let i = 0; i < nums.length; i++) {
        sum += nums[i];
        max = Math.max(max, sum);
        
        if (sum < 0) sum = 0;
    }
    
    return max;
};
```

![](https://i.imgur.com/h6nybVw.png)

### 動態規劃
我們可以從第一個元素開始慢慢找，看包含第一個元素加第二個元素及第二個元素本身的總和哪個大，就選哪個繼續往下做，比如有一陣列為 [-2,1,-3,4,-1,2,1,-5,4]：

1. [-2, 1] 和 [1] 相比 -2 + 1 = -1 < 1，所以 [1] 較大，直接跳過 -2，將 [1] 設為最大子序列起始繼續往下
1. [1, -3] 和 [-3] 是 1 – 3 = -2 > -3，所以將 [1, -3] 繼續往下
1. [1, -3, 4] 和 [4] 是 4 比較大，所以拋棄 [1, -3]，以 [4] 為最大子序列起始再往下做
1. [4, -1] 和 [-1] 相比 4 – 1 = 3 > -1，所以將 [4, -1] 繼續往下
1. [4, -1, 2] 和 [2] 相比 4 – 1 + 2 = 5 > 2 所以將 [4, -1, 2] 繼續往下
1. [4, -1, 2, 1] 和 [1] 相比 4 – 1 + 2 + 1 = 6 > 1 所以將 [4, -1, 2, 1] 繼續往下
1. [4, -1, 2, 1, -5] 和 [-5] 相比 4 – 1 + 2 + 1 – 5 = 1 > -5 所以將 [4, -1, 2, 1, -5] 繼續往下
1. [4, -1, 2, 1, -5, 4] 和 [4] 相比 4 – 1 + 2 + 1 – 5 + 4 = 5 > 4 ，全部元素比較結束。
在這段遍歷中，我們可以得知 [4, -1, 2, 1] 這段子序列的總和是最大的，為 6，所以答案為 6。

比較核心的公式為： `Math.max(arr[i - 1] + nums[i], nums[i]);`

這裡面的 `arr[i]` 代表包含第幾個元素的最大值。

```javascript=
var maxSubArray = function(nums) {
    let arr = [];
    arr[0] = nums[0]; // 子序列必須至少包含一個元素
    let max = arr[0];

    for(let i = 1; i < nums.length; i++) {
        arr[i] = Math.max(arr[i - 1] + nums[i], nums[i]);
        max = Math.max(arr[i], max);
    }

    return max;
};
```

有點難用文字說明，還是看程式碼最快。

![](https://i.imgur.com/rjFxa1D.png)
