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
具体步骤:
- 初始化first和second为最大值
- 遍历数组
- 更新first和second
- 判断是否找到第三个数
时间复杂度: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 | 性能最优 |
代码亮点
- 🎯 O(n)时间复杂度解法
- 💡 O(1)空间复杂度
- 🔍 简洁的贪心策略
- 🎨 清晰的代码结构
常见错误分析
- 🚫 没有处理数组长度小于3的情况
- 🚫 更新first和second的顺序错误
- 🚫 判断条件写反
- 🚫 没有考虑整数溢出
解法对比
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 贪心算法 | O(n) | O(1) | 最优解法 | 不直观 |
| 暴力搜索 | O(n^3) | O(1) | 直观易懂 | 效率低 |
相关题目
- LeetCode 300. 最长递增子序列 - 中等
- LeetCode 354. 俄罗斯套娃信封问题 - 困难
- LeetCode 674. 最长连续递增序列 - 简单
📖 系列导航
🔥 算法专题合集 - 查看完整合集
📢 关注合集更新:点击上方合集链接,关注获取最新题解!目前已更新至第334题。
💬 互动交流
感谢大家耐心阅读到这里!希望这篇题解能够帮助你更好地理解和掌握这道算法题。
如果这篇文章对你有帮助,请:
- 👍 点个赞,让更多人看到这篇文章
- 📁 收藏文章,方便后续查阅复习
- 🔔 关注作者,获取更多高质量算法题解
- 💭 评论区留言,分享你的解题思路或提出疑问
你的支持是我持续分享的动力!
💡 一起进步:算法学习路上不孤单,欢迎一起交流学习!