Article / 文章

LeetCode 第334题:递增的三元子序列

给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。 如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false 。

📖 文章摘要

本文详细解析LeetCode第334题“递增的三元子序列”,这是一道中等难度的数组问题。文章提供了贪心算法的解法,包含C#、Python、C++三种语言实现,配有详细的算法分析和性能对比。适合想要提升数组和贪心算法能力的程序员。

核心知识点: 贪心算法、数组、子序列、双指针
难度等级: 中等
推荐人群: 具有基础算法知识,想要提升贪心算法能力的程序员

题目描述

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

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

示例

示例 1:

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

示例 2:

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

示例 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 * 10^5
  • -2^31 <= nums[i] <= 2^31 - 1
  • 进阶:你能实现时间复杂度为 O(n) ,空间复杂度为 O(1) 的解决方案吗?

解题思路

方法:贪心算法

使用贪心的思想,维护两个变量记录最小值和次小值。

关键点:

  • 维护两个变量first和second
  • first记录当前最小值
  • second记录当前次小值
  • 遇到大于second的数即可返回true

具体步骤:

  1. 初始化first和second为最大值
  2. 遍历数组
  3. 更新first和second
  4. 判断是否找到第三个数

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

图解思路

算法流程分析表

步骤 操作 状态 说明
初始化 first = second = MAX - 初始化两个变量
遇到较小值 更新first first更新 维护最小值
遇到中间值 更新second second更新 维护次小值
遇到较大值 返回true 找到解 满足条件返回

示例分析

nums = [2,1,5,0,4,6]

步骤1: first=2, second=MAX
步骤2: first=1, second=MAX
步骤3: first=1, second=5
步骤4: first=0, second=5
步骤5: first=0, second=4
步骤6: 6>4>0,返回true

代码实现

C# 实现

public class Solution {
    public bool IncreasingTriplet(int[] nums) {
        if (nums == null || nums.Length < 3) return false;
        
        int first = int.MaxValue;
        int second = int.MaxValue;
        
        foreach (int num in nums) {
            if (num <= first) {
                first = num;
            } else if (num <= second) {
                second = num;
            } else {
                return true;
            }
        }
        
        return false;
    }
}

Python 实现

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

C++ 实现

class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        if (nums.size() < 3) return false;
        
        int first = INT_MAX;
        int second = INT_MAX;
        
        for (int num : nums) {
            if (num <= first) {
                first = num;
            } else if (num <= second) {
                second = num;
            } else {
                return true;
            }
        }
        
        return false;
    }
};

执行结果

C# 实现

  • 执行用时:92 ms
  • 内存消耗:42.8 MB

Python 实现

  • 执行用时:48 ms
  • 内存消耗:25.2 MB

C++ 实现

  • 执行用时:4 ms
  • 内存消耗:61.5 MB

性能对比

语言 执行用时 内存消耗 特点
C# 92 ms 42.8 MB 实现简洁
Python 48 ms 25.2 MB 代码最短
C++ 4 ms 61.5 MB 性能最优

代码亮点

  1. 🎯 O(n)时间复杂度解法
  2. 💡 O(1)空间复杂度
  3. 🔍 简洁的贪心策略
  4. 🎨 清晰的代码结构

常见错误分析

  1. 🚫 没有处理数组长度小于3的情况
  2. 🚫 更新first和second的顺序错误
  3. 🚫 判断条件写反
  4. 🚫 没有考虑整数溢出

解法对比

解法 时间复杂度 空间复杂度 优点 缺点
贪心算法 O(n) O(1) 最优解法 不直观
暴力搜索 O(n^3) O(1) 直观易懂 效率低

相关题目


📖 系列导航

🔥 算法专题合集 - 查看完整合集

📢 关注合集更新:点击上方合集链接,关注获取最新题解!目前已更新至第334题。


💬 互动交流

感谢大家耐心阅读到这里!希望这篇题解能够帮助你更好地理解和掌握这道算法题。

如果这篇文章对你有帮助,请:

  • 👍 点个赞,让更多人看到这篇文章
  • 📁 收藏文章,方便后续查阅复习
  • 🔔 关注作者,获取更多高质量算法题解
  • 💭 评论区留言,分享你的解题思路或提出疑问

你的支持是我持续分享的动力!

💡 一起进步:算法学习路上不孤单,欢迎一起交流学习!