力扣-递增的三元子序列

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

思路分析

  1. 创建两个辅助数组:
    • minLeft[i]:记录从数组开始到位置i的最小值(包括nums[i])
    • minRight[i]:记录从位置i到数组结束的最大值(包括nums[i])
  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时,我们已经找到了一个递增对:nums[0]=1 < nums[1]=4
  • 当遇到元素6时,我们有 nums[1]=4 < nums[3]=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)
代码复杂度 较复杂 较简单
实现难度 中等 中等
优势 思路直观,容易理解 空间效率高
相关推荐
小郭团队11 分钟前
1_6_五段式SVPWM (传统算法反正切+DPWM2)算法理论与 MATLAB 实现详解
嵌入式硬件·算法·matlab·dsp开发
小郭团队19 分钟前
1_7_五段式SVPWM (传统算法反正切+DPWM3)算法理论与 MATLAB 实现详解
开发语言·嵌入式硬件·算法·matlab·dsp开发
鱼跃鹰飞22 分钟前
Leetcode347:前K个高频元素
数据结构·算法·leetcode·面试
bybitq23 分钟前
LeetCode236-二叉树的最近公共祖先(LCA)问题详解-C++
算法·深度优先
啊阿狸不会拉杆39 分钟前
《数字图像处理》第 7 章 - 小波与多分辨率处理
图像处理·人工智能·算法·计算机视觉·数字图像处理
程序猿炎义1 小时前
【Easy-VectorDB】Faiss数据结构与索引类型
数据结构·算法·faiss
踢足球09292 小时前
寒假打卡:2026-01-20
职场和发展·学习方法
天赐学c语言2 小时前
1.20 - x的平方根 && vector的扩容机制以及删除元素是否会释放内存
c++·算法·leecode
武清伯MVP2 小时前
聊聊最近的一些面试体验
面试·职场和发展
a努力。3 小时前
字节Java面试被问:TCP的BBR拥塞控制算法原理
java·开发语言·python·tcp/ip·elasticsearch·面试·职场和发展