力扣-递增的三元子序列

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

思路分析

  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)
代码复杂度 较复杂 较简单
实现难度 中等 中等
优势 思路直观,容易理解 空间效率高
相关推荐
IronMurphy12 分钟前
【算法五十六】84. 柱状图中最大的矩形
算法
fie888921 分钟前
matlab打靶法求解两点边值优化问题
开发语言·算法·matlab
酉鬼女又兒34 分钟前
零基础入门计算机网络:第一章概述全解(三种交换方式+八大性能指标+体系结构分层+十年考研真题精讲)
网络协议·计算机网络·考研·网络安全·职场和发展·计算机外设·求职招聘
不做无法实现的梦~37 分钟前
常见工程分析软件
stm32·嵌入式硬件·算法
hetao173383742 分钟前
2026-05-28~06-02 hetao1733837 的刷题记录
c++·算法
ZhengEnCi42 分钟前
O08-单写线程与单读线程冲突分析
算法
仍然.1 小时前
算法题目---优先级队列
算法
一个爱编程的人1 小时前
图的相关概念
c++·算法·图论
迈巴赫车主1 小时前
贪心算法
算法·贪心算法
星马梦缘1 小时前
死锁与进程资源分配问题的解法
算法·操作系统·深度优先·死锁