力扣-递增的三元子序列

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

思路分析

  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)
代码复杂度 较复杂 较简单
实现难度 中等 中等
优势 思路直观,容易理解 空间效率高
相关推荐
To_OC8 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
2401_841495649 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
醇氧11 小时前
CountDownLatch / CyclicBarrier / Semaphore 面试高频问答清单
前端·面试·职场和发展
爱刷碗的苏泓舒13 小时前
PPP-AR 中的参考星选取:数学原理、评价指标与切换处理
算法·gnss·模糊度固定·ppp-ar·星间单差·参考星·卫星端偏差
谙弆悕博士14 小时前
系统集成项目管理工程师教程(第3版)笔记——第17章:法律法规和标准规范
笔记·职场和发展·学习方法·业界资讯·软考·法律·法规
烬羽15 小时前
递归老写崩?一个"退回"公式,把回溯题变成填空题
javascript·深度学习·算法
闪电悠米15 小时前
力扣hot100-41.缺失的第一个正数-原地哈希详解
数据结构·算法·哈希算法
星空露珠16 小时前
28种颜色对应名称,
开发语言·数据库·算法·游戏·lua
QXWZ_IA18 小时前
桥梁数字孪生怎么落地?
人工智能·科技·算法·智能硬件·政务