Featured image of post LeetCode 75系列 - 334. 递增的三元子序列

LeetCode 75系列 - 334. 递增的三元子序列

题目描述

给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。

如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false

示例 1:

1
2
3
输入:nums = [1,2,3,4,5]
输出:true
解释:任何 i < j < k 的三元组都满足题意

示例 2:

1
2
3
输入:nums = [5,4,3,2,1]
输出:false
解释:不存在满足题意的三元组

示例 3:

1
2
3
输入:nums = [2,1,5,0,4,6]
输出:true
解释:三元组 (3, 4, 5) 满足题意,因为 nums[3] == 0 < nums[4] == 4 < nums[5] == 6

提示:

  • 1 <= nums.length <= 5 * 105
  • -231 <= nums[i] <= 231 - 1

题解

使用了贪心算法。

从左到右遍历数组 nums,遍历过程中维护两个变量 first 和 second,分别表示递增的三元子序列中的第一个数和第二个数,任何时候都有 first<second。

初始时,first=nums[0],second=+∞。对于 1≤i<n,当遍历到下标 i 时,令 num=nums[i],进行如下操作:

  1. 如果 num>second,则找到了一个递增的三元子序列,返回 true
  2. 如果 num>first,则将 second的值更新为 num
  3. 否则,将 first 的值更新为 num

如果遍历结束时没有找到递增的三元子序列,返回 false。

上述做法的贪心思想是:为了找到递增的三元子序列,first 和 second 应该尽可能地小,此时找到递增的三元子序列的可能性更大。

简单说就是: 赋初始值时,已经满足 second > first ,现在找第三个数 third

  1. 如果 third 比 second 大,说明找到了,直接返回 true
  2. 如果 third 比 second 小,但是比 first 大,那就把 second 指向 third,然后继续遍历找 third
  3. 如果 third 比 first 还小,那就把 first 指向 third,然后继续遍历找 third(这样的话,first 会跑到 second 的后边,但是不要紧,因为在 second 的前边,旧 first 还是满足的)
 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
class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        if (nums.size() < 3) {
            return false;
        }
        int first = nums[0];
        int second = std::numeric_limits<int>::max();
        
        for (int i = 1; i < nums.size(); i++) {
            // third比second大
            if (nums[i] > second) {
                return true;
            } 
            // third比second小,但比first大
            else if (nums[i] > first) {
                second = nums[i];
            }
            // third比first还小
            else {
                first = nums[i];
            }
        }
        return false;
    }
};
Licensed under CC BY-NC-SA 4.0
最后更新于 Jan 08, 2024 21:41 +0800