问题描述
小S最近在研究一些数组的性质,她发现有一种非常有趣的数组被称为 单调数组。如果一个数组是单调 递增或单调递减的,那么它就是单调的。当对于所有索引i<=j时,nums[i]<= nums[j],数组nums是单调递增的。当对于所有索引i<=j时,nums[i] >= nums[j],数组nums是单调递减的。你需要编写一个程序来判断给定的数组nums是否为单调数组。如果是,返回true,否则返回false。
问题分析
这题是一道简单题,读完题基本上思路就出来了,遍历数组看相邻之间的大小然后记录下来最后判断是递增还是递减就可以了
完整源代码
def solution(nums: list) -> bool:
# write code here
increasing = True
decreasing = True
for i in range(1, len(nums)):
if nums[i] > nums[i - 1]:
decreasing = False
if nums[i] < nums[i - 1]:
increasing = False
return increasing or decreasing
if __name__ == '__main__':
print(solution(nums=[1, 2, 2, 3]) == True)
print(solution(nums=[6, 5, 4, 4]) == True)
print(solution(nums=[1, 3, 2, 4, 5]) == False)
代码分析
细节点1
这里遍历for循环为啥索引从一开始的,0为啥不需要遍历呢? 因为我们的初始比较有nums[i -1]这里已经将零包含在内呢,再减一就越界了
细节点2
有没有什么操作可以提高程序性能呢?
当然,我们可以简化代码的逻辑。实际上,我们只需要遍历一次数组,并且在遍历过程中检查数组是否违反了单调递增或单调递减的性质。如果发现违反的情况,我们可以立即返回False。如果遍历完整个数组都没有发现违反的情况,则返回True,这就是算法题中经常出现的剪枝操作。
优化后的完整源代码
def solution(nums: list) -> bool:
# 初始化标志位
is_increasing = True
is_decreasing = True
# 遍历数组
for i in range(1, len(nums)):
# 检查是否违反单调递增
if nums[i] < nums[i - 1]:
is_increasing = False
# 检查是否违反单调递减
if nums[i] > nums[i - 1]:
is_decreasing = False
# 如果两个标志位都为False,则数组不是单调的
if not is_increasing and not is_decreasing:
return False
# 如果遍历完数组后,至少有一个标志位为True,则数组是单调的
return is_increasing or is_decreasing
if __name__ == '__main__':
print(solution(nums=[1, 2, 2, 3]) == True)
print(solution(nums=[6, 5, 4, 4]) == True)
print(solution(nums=[1, 3, 2, 4, 5]) == False)
代码保姆级解释
- 初始化标志位:
is_increasing和is_decreasing分别表示数组是否单调递增和单调递减。 - 遍历数组:从第二个元素开始,逐个比较当前元素和前一个元素。
- 检查是否违反单调递增或单调递减:如果当前元素小于前一个元素,则数组不是单调递增;如果当前元素大于前一个元素,则数组不是单调递减。
- 提前返回:如果在遍历过程中发现数组既不是单调递增也不是单调递减,则立即返回
False。 - 返回结果:如果遍历完数组后,至少有一个标志位为
True,则数组是单调的。