友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

334. Increasing Triplet Subsequence

更优的解题思路:

首先,新建两个变量 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 的递增序列。 所以,这样的替换并不会干扰我们后续的计算!

参考资料

Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array.

Formally the function should:

<blockquote>Return true if there exists _i, j, k _

such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < kn-1 else return false.</blockquote>

*Note: *Your algorithm should run in O(n) time complexity and O(1) space complexity.

Example 1:

Input: [1,2,3,4,5]
Output: true

Example 2:

Input: [5,4,3,2,1]
Output: false
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
 * Runtime: 0 ms, faster than 100.00% of Java online submissions for Increasing Triplet Subsequence.
 *
 * Memory Usage: 39.3 MB, less than 93.02% of Java online submissions for Increasing Triplet Subsequence.
 */
public boolean increasingTriplet(int[] nums) {
    if (Objects.isNull(nums) || nums.length < 3) {
        return false;
    }
    int small = Integer.MAX_VALUE;
    int mid = Integer.MAX_VALUE;
    for (int i = 0; i < nums.length; i++) {
        int num = nums[i];
        if (num <= small) {
            small = num;
        } else if (num <= mid) {
            mid = num;
        } else if (mid < num) {
            return true;
        }
    }
    return false;
}

/**
 * Runtime: 152 ms, faster than 5.23% of Java online submissions for Increasing Triplet Subsequence.
 *
 * Memory Usage: 40.4 MB, less than 6.98% of Java online submissions for Increasing Triplet Subsequence.
 */
public boolean increasingTripletDp(int[] nums) {
    if (Objects.isNull(nums) || nums.length < 3) {
        return false;
    }
    int[] dp = new int[nums.length];
    Arrays.fill(dp, 1);
    int max = 1;
    for (int i = 1; i < nums.length; i++) {
        for (int j = 0; j < i; j++) {
            if (nums[j] < nums[i]) {
                dp[i] = Math.max(dp[i], dp[j] + 1);
            }
        }
        max = Math.max(max, dp[i]);
        if (max >= 3) {
            return true;
        }
    }
    return false;
}