---
# System prepended metadata

title: 【6-0】演算法介紹

---

# 【6-0】演算法介紹

演算法（Algorithm） 是指一組「清楚定義的步驟」或「處理流程」，用來有效解決某一類問題。在程式語言的世界中，演算法不只是解題的工具，更是影響「程式效率」的關鍵因素。

- 語法讓你寫出可以執行的程式
- 邏輯賦予程式功能
- 演算法讓程式有效率、巧妙的解決問題

在[【5-0】複雜度估計法](https://hackmd.io/@LAfWxjSxRASps-4O_bppsA/B1bcXCEHgx) 我們已經學習過複雜度估計法，而複雜度正是演算法當中評斷好與壞的重要指標。

前四章學習的是基礎語法、邏輯，第五章學習的是複雜度低的工具，現在我們要把前五章學習到的內容組合起來，成為演算法。


## 範例

給定一個長度為 `n` 的整數陣列 `a[0…n-1]`，請找出一個連續子陣列，使其所有元素和最大，並輸出這個最大和。

例如，對陣列 `[-2, 1, -3, 4, -1, 2, 1, -5, 4]`，最大連續子陣列是 `[4, -1, 2, 1]`，其和為 `6`。

### 解法 1：三層迴圈暴力枚舉

最直觀的方法，枚舉所有可能的起點 `i` 和終點 `j`，累加 `a[i] + a[i+1] + … + a[j]`，並維護最大值。

```cpp=
int maxSubArray(vector<int>& a) {
    int n = a.size();
    int best = INT_MIN;
    // O(n²)枚舉子陣列
    for (int i = 0; i < n; ++i) {
        for (int j = i; j < n; ++j) {
            // O(n)區間和
            int sum = 0;
            for (int k = i; k <= j; ++k) {
                sum += a[k];
            }
            best = max(best, sum);
        }
    }
    return best;
}
```

* **時間複雜度**：O(n³)

### 解法 2：前綴和 + 雙層枚舉

利用前綴和（prefix sum）陣列 `ps`，使每次區間和計算從 O(n) 降到 O(1)。

1. 先建 `ps[0] = 0`，`ps[i] = a[0] + … + a[i-1]`。
2. 區間 `i…j` 的和就是 `ps[j+1] - ps[i]`。

```cpp=
int maxSubArray(vector<int>& a) {
    int n = a.size();
    // O(n)前綴和
    vector<int> ps(n + 1, 0);
    for (int i = 0; i < n; ++i)
        ps[i + 1] = ps[i] + a[i];

    int best = INT_MIN;
    // O(n²)枚舉子陣列
    for (int i = 0; i < n; ++i) {
        for (int j = i; j < n; ++j) {
            // O(1)區間和
            int sum = ps[j + 1] - ps[i];
            best = max(best, sum);
        }
    }
    return best;
}

```

* **時間複雜度**：O(n²)

---

### 解法 3：Kadane’s Algorithm（線性掃描）

Kadane 演算法只需一次掃描，就能在 O(n) 內解出最大和。思路是：

1. 設 `curr = a[0]`, `best = a[0]`
2. 每向右移一格 `i`，更新
   ```
   curr = max(a[i], curr + a[i]);
   best = max(best, curr);
   ```
   其中 `curr` 代表「以 i 結尾的最大子陣列和」。

```cpp=
int maxSubArray(vector<int>& a) {
    int n = a.size();
    int curr = a[0], best = a[0];
    // O(n)線性掃描找以 i 結尾的最大子陣列和
    for (int i = 1; i < n; ++i) {
        curr = max(a[i], curr + a[i]);
        best = max(best, curr);
    }
    return best;
}
```

* **時間複雜度**：O(n)

## 結論

在接下來的單元，我們將著重介紹各類演算法的思路，並提供範例來講解演算法在題目中的應用，比較同一題的各類演算法效率，建議讀者熟讀第五章及以前的所有內容，再來看演算法。

---

聯絡方式：codecodefunny@gmail.com
最後編修時間：2025/08/02 子柚筆
