【LeetCode 每日一题】3637. 三段式数组 I——(解法二)一次循环

Problem: 3637. 三段式数组 I

文章目录

  • [1. 整体思路](#1. 整体思路)
  • [2. 完整代码](#2. 完整代码)
  • [3. 时空复杂度](#3. 时空复杂度)
      • [时间复杂度: O ( N ) O(N) O(N)](#时间复杂度: O ( N ) O(N) O(N))
      • [空间复杂度: O ( 1 ) O(1) O(1)](#空间复杂度: O ( 1 ) O(1) O(1))

1. 整体思路

核心问题

我们需要验证数组是否为 升 -> 降 -> 升 的形状。

这个形状特征可以转化为单调性的变化次数

  1. 开始 :必须是上升的 (up)。
  2. 转折点 1 (峰) :从 变为
  3. 转折点 2 (谷) :从 变为
  4. 结束:必须保持上升状态直到结束,不能再有转折点。

这意味着,整个数组应该恰好包含 2 个转折点 ,或者说包含 3 个单调区间 (升、降、升)。

算法逻辑

  1. 初始检查nums[0] >= nums[1]。如果开头不是上升的,直接返回 false
  2. 计数器 cnt:初始化为 1,代表这是第 1 个单调区间(初始的上升段)。
  3. 遍历 :从 i = 2 开始遍历到末尾。
    • 平坡检查 :如果 nums[i-1] == nums[i],说明有平坡,不符合严格单调性,返回 false
    • 转折点检测
      • nums[i-2] < nums[i-1]:前一步是上升。
      • nums[i-1] < nums[i]:当前步是上升。
      • 如果这两个状态不一致(例如前一步升,当前步降;或前一步降,当前步升),说明发生了转折。
      • 发生转折时,区间计数 cnt++
  4. 最终检查 :如果 cnt == 3,说明恰好经历了"升 -> 降 -> 升"三个阶段,且没有多余的转折,返回 true

2. 完整代码

java 复制代码
class Solution {
    public boolean isTrionic(int[] nums) {
        // 边界条件:数组长度过短无法形成三段
        if (nums.length < 4) {
             return false;
        }

        // 1. 检查起始段
        // 必须以严格递增开始
        if (nums[0] >= nums[1]) {
            return false;
        }

        // cnt 记录单调区间的数量
        // 初始为 1,因为我们已经确认了开头是上升区间
        int cnt = 1;
        
        // 2. 遍历数组,检测转折点
        for (int i = 2; i < nums.length; i++) {
            // 严格单调性检查:不允许相等元素(平坡)
            if (nums[i - 1] == nums[i]) {
                return false;
            }
            
            // 核心逻辑:检测单调性是否改变
            // condition1: nums[i-2] < nums[i-1] (前一步是上升吗?)
            // condition2: nums[i-1] < nums[i]   (当前步是上升吗?)
            // 如果两个条件真假不同 (即 !=),说明单调性发生了反转 (峰或谷)
            if ((nums[i - 2] < nums[i - 1]) != (nums[i - 1] < nums[i])) {
                cnt++;
            }
        }
        
        // 3. 最终校验
        // cnt == 3 意味着经历了: 上升(1) -> 峰转折 -> 下降(2) -> 谷转折 -> 上升(3)
        // 且最后没有再转折,保持上升直到结束
        return cnt == 3;
    }
}

3. 时空复杂度

假设数组 nums 的长度为 N N N。

时间复杂度: O ( N ) O(N) O(N)

  • 计算依据
    • 代码包含一次 for 循环,从 2 遍历到 N N N。
    • 循环内部只包含常数次比较和自增操作。
  • 结论 : O ( N ) O(N) O(N)。

空间复杂度: O ( 1 ) O(1) O(1)

  • 计算依据
    • 只使用了常数个整型变量 (cnt, i)。
  • 结论 : O ( 1 ) O(1) O(1)。

参考灵神

相关推荐
努力学算法的蒟蒻17 小时前
day115(3.17)——leetcode面试经典150
面试·职场和发展
老鱼说AI17 小时前
CUDA架构与高性能程序设计:异构数据并行计算
开发语言·c++·人工智能·算法·架构·cuda
罗湖老棍子18 小时前
【例 1】数列操作(信息学奥赛一本通- P1535)
数据结构·算法·树状数组·单点修改 区间查询
big_rabbit050218 小时前
[算法][力扣222]完全二叉树的节点个数
数据结构·算法·leetcode
张李浩18 小时前
Leetcode 15三题之和
算法·leetcode·职场和发展
2301_7938046919 小时前
C++中的适配器模式变体
开发语言·c++·算法
x_xbx19 小时前
LeetCode:206. 反转链表
算法·leetcode·链表
abant219 小时前
leetcode 138 复制随机链表
算法·leetcode·链表
ab15151719 小时前
3.17二刷基础112 118 完成进阶52
数据结构·算法
旖-旎20 小时前
二分查找(1)
c++·算法·二分查找·力扣·双指针