问题描述
小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。同时给出了几个典型的测试样例,方便我们直观理解不同情况下的期望输出,像单调递增、单调递减以及非单调这几种情况都有所涉及。
思路步骤
-
初始化标记变量:
首先定义了两个布尔类型的变量increasing和decreasing,并都初始化为True。这里的increasing用于标记该列表是否是单调递增的情况,而decreasing则用于标记列表是否是单调递减的情况。 -
通过循环遍历判断单调性:
使用for循环来遍历列表nums,循环范围是从索引1到列表长度减1(即range(1, len(nums))),这样就能依次比较列表中相邻的元素。- 判断递减情况:在每次循环中,当发现当前元素
nums[i]大于前一个元素nums[i - 1]时,意味着出现了递增的元素变化,此时就可以确定该列表不可能是单调递减的了,所以将decreasing变量更新为False。 - 判断递增情况:相反,若当前元素
nums[i]小于前一个元素nums[i - 1],这表明出现了递减的元素变化,也就意味着该列表不可能是单调递增的了,进而将increasing变量更新为False。
- 判断递减情况:在每次循环中,当发现当前元素
-
根据标记变量确定返回结果:
在遍历完整个列表后,通过逻辑表达式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)。