---
# System prepended metadata

title: 'LeetCode 日記 #008: 334. Increasing Triplet Subsequence | 貪心算法 Greedy'
tags: [LeetCode, Java, Algorithm, Data Structure]

---

# LeetCode 日記 #008: 334. Increasing Triplet Subsequence | 貪心算法 Greedy

> Given an integer array nums, return true if there exists a triple of indices (i, j, k) such that i < j < k and nums[i] < nums[j] < nums[k]. If no such indices exists, return false.

- **Example 1:**
    Input: nums = [1,2,3,4,5]
    Output: true
    Explanation: Any triplet where i < j < k is valid.
    
- **Example 2:**
    Input: nums = [5,4,3,2,1]
    Output: false
    Explanation: No triplet exists.
    
- **Example 3:**
    Input: nums = [2,1,5,0,4,6]
    Output: true
    Explanation: nums[3] == 0 < nums[4] == 4 < nums[5] == 6.
    
### 題目概述

判斷題目給定的原始陣列中，是否存在連續三個元素是呈現遞增的子陣列，有的話返回 true，沒有則返回 false。要解決這題就必須學習一個新的算法思想與策略——**貪心算法 (Greedy)**。

## 貪心算法 (Greedy)

貪心算法的核心思想是，在每一步選擇中都採取當前狀態下最優的選擇（局部最優），期待最終能得到「全局最優」。

### 特性

* **局部最優選擇**：每一步的選擇都是當前看起來最好的，不考慮全局
* **無後效性**：當前的決策不會影響未來的決策
* **子問題最優性質**：問題的最優解包含子問題的最優解
* **簡單高效**：通常實現簡單且時間複雜度較低
* **不需要回溯**：一旦做出選擇，就不會回頭重新考慮

### 使用時機

* **問題可以分解為子問題**：整體問題可以分解為一系列子問題
* **滿足最優子結構**：問題的最優解包含子問題的最優解
* **具有貪心選擇性質**：每一步的局部最優選擇能導致全局最優解
* **子問題之間相互獨立**：一個子問題的解不會影響其他子問題

判斷問題是否適合使用貪心算法，可以考慮以下幾點：

* **「問題是否有明顯的局部最優選擇」**：例如「選擇當前最小/最大值」
* **「局部最優是否能推導出全局最優」**：需要證明局部選擇不會導致次優解
* **「問題是否具有無後效性」**：當前決策不會影響未來的決策空間
* **「問題是否具有貪心選擇性質」**：每一步的最優選擇能導致全局最優解

## 題解

第一眼看到這題時，可從以下幾個角度來分析是否適用貪心算法：

1. **問題結構**：
    首先，觀察到這個問題的核心是尋找三個遞增的元素，而不是求所有可能的遞增子序列。這種「是否存在」的問題通常比「找出所有」的問題更適合使用貪心或者更簡單的算法。
    
2. **子問題與獨立性分析**：
    當分析如何判斷陣列中是否存在遞增的三元組時，關鍵問題變成：
    - 如何有效地記錄已經看到的最小值
    - 如何記錄基於這個最小值的第二小值
    - 如何判斷是否存在第三個值大於前兩個值

>     這種子問題結構表明可能不需要記住所有歷史信息，只需要記住關鍵狀態。
    
3. **最優子結構特性識別**：
    如果已經找到當前最小值 first 和第二小值 second，那麼只要找到任何一個大於 second 的值，就能確定存在遞增三元組，這符合貪心算法的最優子結構特性 - 維護當前最優的 first 和 second 有助於找到全局解。
    
4. **局部最優選擇分析**：
    考慮在迭代時的每一步決策，如果遇到一個更小的值，更新 first 是局部最優的（讓後續找到合適的 second 和第三個值的可能性更大）如果遇到一個介於 first 和 second 之間的值，更新 second 是局部最優的，如果遇到一個大於 second 的值，我們直接找到了答案。這種每一步的局部最優選擇，能夠指向全局最優解，是貪心算法的核心特徵。
    
5. **無後效性判斷**：
    當我更新 first 或 second 時，我不需要考慮它們之前的值或相對位置，只關心數值大小關係。這種特性表明問題具有無後效性，適合使用貪心算法。

```java
class Solution {
    public boolean increasingTriplet(int[] nums) {
        int first = Integer.MAX_VALUE;
        int second = Integer.MAX_VALUE;

        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > second) {
                return true;
            } else if (nums[i] > first && nums[i] < second) {
                second = nums[i];
            } else if (nums[i] < first) {
                first = nums[i];
            }
        }
        return false;
    }
}

```

### 總結
綜合以上分析，當看到這類「尋找特定模式」且只需要「是/否」答案的問題時，可優先考慮是否適用貪心算法。特別是當問題可以通過維護少量關鍵變量（如 first 和 second）來表達狀態，並且每一步都有明確的局部最優選擇時。如果使用貪心策略，整個算法只需要 O(n) 的時間複雜度和 O(1) 的空間複雜度，非常高效。貪心算法通常比動態規劃或回溯算法更簡潔高效。