---
# System prepended metadata

title: 0334. Increasing Triplet Subsequence
tags: [Leetcode, Array, Medium]

---

# 0334. Increasing Triplet Subsequence
###### tags: `Leetcode` `Medium` `Array`
## 思路
非常tricky的一道题
之前想的办法是遍历的过程中，记录下来前面出现过的最小的数当作开头，如果碰到一个数比前面最小的数小，那么就开始遍历后面，看有没有比这个数大的数，有的话就回传true，但这个方法由于复杂度是O(N^2)，就TLE了
题目要找的是 **时间复杂度O（N），空间复杂度O(1)** 的

**正确思路：**
首先，新建两个变量 small 和 mid ，分别用来保存题目要我们求的长度为 3 的递增子序列的最小值和中间值。

接着，我们遍历数组，每遇到一个数字，我们将它和 small 和 mid 相比，若小于等于 small ，则替换 small；否则，若小于等于 mid，则替换 mid；否则，若大于 mid，则说明我们找到了长度为 3 的递增数组！

上面的求解过程中有个问题：当已经找到了长度为 2 的递增序列，这时又来了一个比 small 还小的数字，为什么可以直接替换 small 呢，这样 small 和 mid 在原数组中并不是按照索引递增的关系呀？

Trick 就在这里了！假如当前的 small 和 mid 为 [3, 5]，这时又来了个 1。假如我们不将 small 替换为 1，那么，当下一个数字是 2，后面再接上一个 3 的时候，我们就没有办法发现这个 [1,2,3] 的递增数组了！也就是说，我们替换最小值，是为了后续能够更好地更新中间值！

另外，即使我们更新了 small ，这个 small 在 mid 后面，没有严格遵守递增顺序，但它隐含着的真相是，有一个比 small 大比 mid 小的前·最小值出现在 mid 之前。因此，当后续出现比 mid 大的值的时候，我们一样可以通过当前 small 和 mid 推断的确存在着长度为 3 的递增序列。 所以，这样的替换并不会干扰我们后续的计算！


## Code in Java
```java=
class Solution {
    public boolean increasingTriplet(int[] nums) {
        int small = Integer.MAX_VALUE,mid = Integer.MAX_VALUE;
        for(int num:nums){
            if(num<small) small = num;
            else if(small<num && num<mid) mid = num;
            else if(num>mid) return true;
        }
        return false;
    }
}
```
## Result
Runtime: 2 ms, faster than **64.10%** of Java online submissions for Increasing Triplet Subsequence.
Memory Usage: 80 MB, less than **98.40%** of Java online submissions for Increasing Triplet Subsequence.