跳至主要內容

0334. 递增的三元子序列

ITCharge大约 2 分钟

0334. 递增的三元子序列open in new window

  • 标签:贪心、数组
  • 难度:中等

题目链接

题目大意

描述:给定一个整数数组 numsnums

要求:判断数组中是否存在长度为 3 的递增子序列。

说明

  • 要求算法时间复杂度为 O(n)O(n)、空间复杂度为 O(1)O(1)
  • 长度为 33 的递增子序列:存在这样的三元组下标 (ii, jj, kk) 且满足 i<j<ki < j < k ,使得 nums[i]<nums[j]<nums[k]nums[i] < nums[j] < nums[k]
  • 1nums.length5×1051 \le nums.length \le 5 \times 10^5
  • 231nums[i]2311-2^{31} \le nums[i] \le 2^{31} - 1

示例

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

解题思路

思路 1:快慢指针

常规方法是三重 for 循环遍历三个数,但是时间复杂度为 O(n3)O(n^3),肯定会超时的。

那么如何才能只进行一次遍历,就找到长度为 3 的递增子序列呢?

假设长度为 3 的递增子序列元素为 aabbcca<b<ca < b < c

先来考虑 aabb。如果我们要使得一个数组 i<ji < j,并且 nums[i]<nums[j]nums[i] < nums[j]。那么应该使得 aa 尽可能的小,这样子我们下一个数字 bb 才可以尽可能地满足条件。

同样对于 bbcc,也应该使得 bb 尽可能的小,下一个数字 cc 才可以尽可能的满足条件。

所以,我们的目的是:在 a<ba < b 的前提下,保证 a 尽可能小。在 b<cb < c 的条件下,保证 bb 尽可能小。

我们可以使用两个数 aabb 指向无穷大。遍历数组:

  • 如果当前数字小于等于 aa ,则更新 a = num
  • 如果当前数字大于等于 aa,则说明当前数满足 num>anum > a,则判断:
    • 如果 numbnum \le b,则更新 b = num
    • 如果 num>bnum > b,则说明找到了长度为 3 的递增子序列,直接输出 TrueTrue
  • 如果遍历完仍未找到,则输出 FalseFalse

思路 1:代码

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

思路 1:复杂度分析

  • 时间复杂度O(n)O(n)
  • 空间复杂度O(1)O(1)