力扣-递增的三元子序列

方法一:预处理左右最值数组

思路分析

  1. 创建两个辅助数组:
    • minLeft[i]:记录从数组开始到位置i的最小值(包括numsi
    • minRight[i]:记录从位置i到数组结束的最大值(包括numsi
  2. 遍历数组,对每个位置i,检查是否存在 minLeft[i] < nums[i] < minRight[i]
  3. 如果存在,则说明找到了递增三元组

代码实现

java 复制代码
public boolean increasingTriplet(int[] nums){
    boolean flag = false;
    int[] minLeft = new int[nums.length];
    int[] minRight = new int[nums.length];
    
    // 初始化minLeft数组
    minLeft[0] = nums[0];
    // 初始化minRight数组
    minRight[nums.length-1] = nums[nums.length-1];
    
    // 正序遍历,构建minLeft数组
    for (int i = 1; i < nums.length; i++) {
        minLeft[i] = Math.min(minLeft[i-1], nums[i]);
    }
    
    // 倒序遍历,构建minRight数组
    for (int i = nums.length-2; i >= 0; i--) {
        minRight[i] = Math.max(minRight[i+1], nums[i]);
    }
    
    // 检查是否存在递增三元组
    for (int i = 0; i < nums.length; i++) {
        if (minLeft[i] < nums[i] && nums[i] < minRight[i]) {
            flag = true;
        }
    }
    return flag;
}

复杂度分析

  • 时间复杂度:O(n),需要三次遍历数组
  • 空间复杂度:O(n),需要两个额外的数组

方法二:贪心算法

思路分析

  1. 维护两个变量:
    • first:记录当前找到的最小值
    • second:记录当前找到的第二个值(比first大的最小值)
  2. 遍历数组:
    • 如果当前数字小于等于first,更新first
    • 如果当前数字大于first但小于等于second,更新second
    • 如果当前数字大于second,说明找到了递增三元组,返回true
  3. 如果遍历完都没找到,返回false

代码实现

java 复制代码
public boolean increasingTriplet2(int[] nums) {
    int first = Integer.MAX_VALUE;
    int second = Integer.MAX_VALUE;
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] <= first){
            first = nums[i];
        }else if (nums[i] <= second){
            second = nums[i];
        }else {
            return true;
        }
    }
    return false;
}

注意点

  1. 在遍历过程中可能会出现first在second后面的情况,但是没关系,最终任然能找到正确的三元组,我们以数组{1,4,0,6}为例,
  • 初始状态:first = Integer.MAX_VALUE, second = Integer.MAX_VALUE
  • num = 1:
    1 <= first(Integer.MAX_VALUE) → 更新 first = 1
    状态:first = 1, second = Integer.MAX_VALUE
  • num = 4:
    4 > first(1) 且 4 <= second(Integer.MAX_VALUE) → 更新 second = 4
    状态:first = 1, second = 4
  • num = 0:
    0 <= first(1) → 更新 first = 0
    状态:first = 0, second = 4
  • num = 6:
    6 > first(0) 且 6 > second(4) → 满足条件 first < second < num,返回 true
  • 最终状态:
    first = 0 (对应数组索引2的元素)
    second = 4 (对应数组索引1的元素)
重要说明:

虽然最终 first 指向的是数组中索引为2的元素0,second 指向的是索引为1的元素4,但算法仍然正确地找到了递增三元组。这是因为:

  • 在处理元素4时,我们已经找到了一个递增对:nums0=1 < nums1=4
  • 当遇到元素6时,我们有 nums1=4 < nums3=6
  • 虽然 first 的值被更新为0,但 second=4 仍然表示在某个较小值之后出现的较大值
  • 所以 first=0 < second=4 < num=6 形成了一个有效的递增三元组
  1. 注意判断条件是小于等于,而不是小于
    例如测试数组{1,1,1,1,1,},如果使用的是小于,则会返回true,实际上正确结果应该是false。
  • i = 0, num = 1:1 < Integer.MAX_VALUE → first = 1
  • i = 1, num = 1:1 < 1 → 不满足,进入 else if → 1 < Integer.MAX_VALUE → second = 1
  • i = 2, num = 1:1 < 1 → 不满足,1 < 1 → 不满足,进入 else → return true

复杂度分析

  • 间复杂度:O(n),只需一次遍历数组
  • 空间复杂度:O(1),只使用了常数级额外空间

对比总结

特征 方法一(预处理数组) 方法二(贪心算法)
时间复杂度 O(n) O(n)
空间复杂度 O(n) O(1)
代码复杂度 较复杂 较简单
实现难度 中等 中等
优势 思路直观,容易理解 空间效率高
相关推荐
地平线开发者15 分钟前
BEVdet模型解析
算法·自动驾驶
tudousisi22229 分钟前
P2758 编辑距离 题解复盘
算法
李可以量化41 分钟前
Tornado 从了解到精通(四)上:实战搭建 Web 应用与核心组件详解
算法
linux-hzh1 小时前
百日算法修炼 · Day 09
数据结构·算法·排序算法
DFT计算杂谈1 小时前
Janus单层Cr2SSe中的应变可调多压电效应与谷电子学
人工智能·算法·机器学习
今天AI了吗1 小时前
从 LLM 到 Agent Skill:把 AI 底层概念串起来
数据库·人工智能·sql·深度学习·神经网络·算法·机器学习
hanlin032 小时前
动态规划专练:力扣第1035、392题
算法·leetcode·动态规划
淡海水2 小时前
C#与常用数据结构源码剖析-全篇导览
开发语言·数据结构·unity·面试·职场和发展·c#
不正经学生2 小时前
C语言大小端字节序:内存里字节的排列顺序
c语言·开发语言·arm开发·c++·算法·c#
大模型探索者2 小时前
2026金融大模型训推平台选型指南:主流厂商横向对比与私有化落地
人工智能·算法·金融