题目解析:判断数组是否单调 | 豆包MarsCode AI 刷题

55 阅读3分钟

问题描述

小S最近在研究一些数组的性质,她发现有一种非常有趣的数组被称为 单调数组。如果一个数组是单调递增或单调递减的,那么它就是单调的。

  • 当对于所有索引i <= j时,nums[i] <= nums[j],数组nums是单调递增的。
  • 当对于所有索引i <= j时,nums[i] >= nums[j],数组nums是单调递减的。

你需要编写一个程序来判断给定的数组nums是否为单调数组。如果是,返回true,否则返回false


测试样例

样例1:

输入:nums = [1, 2, 2, 3]
输出:True

样例2:

输入:nums = [6, 5, 4, 4]
输出:True

样例3:

输入:nums = [1, 3, 2, 4, 5]
输出:False

题目分析

  • 题目定义明确:题目清晰地给出了单调数组的定义,即单调递增(对于所有 i <= j,都有 nums[i] <= nums[j])或者单调递减(对于所有 i <= j,都有 nums[i] >= nums[j])的数组就是单调数组,需要我们依据此定义去判断给定的数组是否符合要求。
  • 输入输出明确:输入是一个整数数组 nums,输出则是一个布尔值,若数组是单调数组就返回 True,不是则返回 False。同时给出了几个典型的测试样例,方便我们直观理解不同情况下的期望输出,像单调递增、单调递减以及非单调这几种情况都有所涉及。

思路步骤

  1. 初始化标记变量
    首先定义了两个布尔类型的变量 increasing 和 decreasing,并都初始化为 True。这里的 increasing 用于标记该列表是否是单调递增的情况,而 decreasing 则用于标记列表是否是单调递减的情况。

  2. 通过循环遍历判断单调性
    使用 for 循环来遍历列表 nums,循环范围是从索引 1 到列表长度减 1(即 range(1, len(nums))),这样就能依次比较列表中相邻的元素。

    • 判断递减情况:在每次循环中,当发现当前元素 nums[i] 大于前一个元素 nums[i - 1] 时,意味着出现了递增的元素变化,此时就可以确定该列表不可能是单调递减的了,所以将 decreasing 变量更新为 False
    • 判断递增情况:相反,若当前元素 nums[i] 小于前一个元素 nums[i - 1],这表明出现了递减的元素变化,也就意味着该列表不可能是单调递增的了,进而将 increasing 变量更新为 False
  3. 根据标记变量确定返回结果
    在遍历完整个列表后,通过逻辑表达式 increasing or decreasing 来综合判断列表的单调性。只要 increasing 或者 decreasing 其中有一个为 True,就说明列表要么是单调递增的,要么是单调递减的,整体满足单调的定义,此时函数就返回 1;而如果 increasing 和 decreasing 都为 False,那就表示列表既不是单调递增也不是单调递减,即不是单调数组,函数就返回 0

完整代码

def solution(nums: list) -> int:
    increasing = decreasing = True
    for i in range(1, len(nums)):
        if nums[i] > nums[i - 1]:
            decreasing = False
        elif nums[i] < nums[i - 1]:
            increasing = False       
    return 1 if increasing or decreasing else 0
    
if __name__ == '__main__':
    print(solution(nums=[1, 2, 2, 3]) == 1)
    print(solution(nums=[6, 5, 4, 4]) == 1)
    print(solution(nums=[1, 3, 2, 4, 5]) == 0)

复杂度分析

时间复杂度方面,由于只需遍历一次列表 nums,每次遍历进行常数次操作,所以时间复杂度为O(n),其中 n 是列表 nums 的长度;空间复杂度上,代码中只额外使用了两个常数级别的布尔变量 increasing 和 decreasing,不随输入列表长度变化而变化,所以空间复杂度为O(1)。