力扣-递增的三元子序列

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

思路分析

  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 小时前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰18 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术19 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六1 天前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术1 天前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize1 天前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考2 天前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队2 天前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode