在问 · 算法题解

334. 递增的三元子序列

中等贪心贪心(维护两个最小值)力扣原题 ↗

题目描述

输入一个整数数组 nums。判断能否从中挑出三个元素,它们的下标满足 i < j < k,数值满足 nums[i] < nums[j] < nums[k]。

也就是判断数组里是否存在长度为 3 的严格递增子序列。存在就返回 true,不存在返回 false。

示例 1
输入:nums = [1,2,3,4,5]
输出:true

解释:任取三个下标递增的元素都满足条件。

示例 2
输入:nums = [5,4,3,2,1]
输出:false

解释:数组严格递减,找不到这样的三个数。

示例 3
输入:nums = [2,1,5,0,4,6]
输出:true

解释:取下标 1,4,5,对应 1 < 4 < 6。

数据范围

  • 1 <= nums.length <= 5 * 10^5
  • -2^31 <= nums[i] <= 2^31 - 1

进阶:能否做到时间复杂度 O(n)、额外空间 O(1)?

解题思路:贪心(维护两个最小值)

维护两个值:first 是目前见过的最小值,second 是“前面有更小数的”最小次大值。遍历时贪心地让这两个值尽可能小:x ≤ first 就更新 first,否则 x ≤ second 就更新 second,否则 x 比两者都大,找到了三元组。

为什么正确

second 不是正无穷时,它前面一定有一个更小的数。first 更新到 second 后面也不影响这一点,因为旧的更小数仍在 second 前面。

复杂度分析

时间 O(n),空间 O(1)。

易错点

要用 <= 而不是 <:相等的数不能算严格递增。first 更新后不要重置 second。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def increasingTriplet(self, nums: List[int]) -> bool:
        first = float('inf')
        second = float('inf')
        for x in nums:
            if x <= first:
                first = x
            elif x <= second:
                second = x
            else:
                return True
        return False

载入编辑器,自己跑一遍 →

其他解法

前后缀数组枚举中间元素,用 O(n) 空间换来直观性;贪心只维护 first 和 second 两个变量,空间 O(1)。

解法 2:前缀最小 + 后缀最大 时间 O(n),空间 O(n)

leftMin[i] 记录 nums[0..i] 的最小值,rightMax[i] 记录 nums[i..n-1] 的最大值。枚举中间元素 nums[i],只要 leftMin[i-1] < nums[i] < rightMax[i+1],就存在递增三元组。

思路直观,容易证明正确。需要两个长度为 n 的辅助数组,不满足进阶要求的 O(1) 空间。

class Solution:
    def increasingTriplet(self, nums: List[int]) -> bool:
        n = len(nums)
        if n < 3:
            return False
        left_min = [0] * n
        left_min[0] = nums[0]
        for i in range(1, n):
            left_min[i] = min(left_min[i - 1], nums[i])
        right_max = [0] * n
        right_max[n - 1] = nums[n - 1]
        for i in range(n - 2, -1, -1):
            right_max[i] = max(right_max[i + 1], nums[i])
        for i in range(1, n - 1):
            if left_min[i - 1] < nums[i] < right_max[i + 1]:
                return True
        return False

贪心 专题的其他题目

查看 贪心 全部题目 →