判断数组是否单调 问题描述 小S最近在研究一些数组的性质,她发现有一种非常有趣的数组被称为 单调数组。如果一个数组是单调递增或单调递减的,那么它就是单调的。 当对于所有索引li<=j时,nums[i]<=nums[j],数组nums是单调递增的。 当对于所有索引i<=j时,nums[i]>=nums[j],数组nums是单调递减的。 你需要编写一个程序来判断给定的数组nums是否为单调数组。如果是,返回true,否则返回fals 代码展示
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)
一、题目解析
- 题目要求:给定一个数组,判断其是否为单调数组。单调数组分为单调递增和单调递减两种情况。
- 单调递增定义:数组中任意一个元素都大于等于它前面相邻的元素,例如:[2, 2, 3, 4, 5] 就是单调递增数组。
- 单调递减定义:数组中任意一个元素都小于等于它前面相邻的元素,像 [5, 4, 3, 3, 2] 属于单调递减数组。
- 非单调判定:若数组中存在某个元素,其既不满足单调递增条件(大于等于前一个元素),也不满足单调递减条件(小于等于前一个元素),则该数组不是单调数组,比如 [1, 3, 2, 4] 就不符合单调要求。
二、代码解析(以Python为例)
def isMonotonic(nums):
if len(nums) <= 1:
return True
increasing = True
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 increasing or decreasing
- 代码思路详解:
- 首先处理边界情况,当数组长度小于等于1时,按照定义,这样的数组可视为既是单调递增又是单调递减的,所以直接返回 True 。
- 接着初始化两个布尔变量 increasing 和 decreasing ,分别用于标记数组是否有可能是单调递增和单调递减的状态,初始都设为 True 。
- 然后通过循环遍历数组,从索引为1的元素开始(因为要和前一个元素比较,索引0的元素无前一个元素可比较),每次比较当前元素 nums[i] 和它前一个元素 nums[i - 1] 的大小关系:
- 若 nums[i] 大于 nums[i - 1] ,这就不符合单调递减的定义,所以将 decreasing 设为 False 。
- 若 nums[i] 小于 nums[i - 1] ,则不符合单调递增的定义,将 increasing 设为 False 。
- 最后,只要 increasing 或者 decreasing 其中一个为 True ,就表明数组满足单调的条件,返回这个结果。
三、在题目中遇到的困难及解决办法
困难一:对单调概念的准确理解
- 问题描述:
- 初次接触时,可能对单调递增和单调递减的严格定义理解模糊,不清楚到底是严格大于、小于还是可以等于前一个元素,导致在编写判断逻辑时出错。
- 解决办法:
- 仔细研读题目中给出的关于单调递增(每个元素大于等于它前面相邻的元素)和单调递减(每个元素小于等于它前面相邻的元素)的定义描述,并且手动列举多个不同情况的数组示例,按照定义去逐一分析判断它们是否单调,以此加深对概念的理解。例如:
示例数组1:单调递增
nums1 = [1, 1, 2, 3, 3]
for i in range(1, len(nums1)):
if nums1[i] < nums1[i - 1]:
print("该数组不是单调递增数组,因为", nums1[i], "小于", nums1[i - 1])
else:
print("数组", nums1, "是单调递增数组")
示例数组2:单调递减
nums2 = [5, 4, 3, 2, 2]
for i in range(1, len(nums2)):
if nums2[i] > nums2[i - 1]:
print("该数组不是单调递减数组,因为", nums2[i], "大于", nums2[i - 1])
else:
print("数组", nums2, "是单调递减数组")
示例数组3:非单调
nums3 = [1, 3, 2, 4]
is_monotonic = True
for i in range(1, len(nums3)):
if nums3[i] < nums3[i - 1]:
increasing = False
elif nums3[i] > nums3[i - 1]:
decreasing = False
if not increasing and not decreasing:
is_monotonic = False
break
if is_monotonic:
print("数组", nums3, "是单调数组")
else:
print("数组", nums3, "不是单调数组")
困难二:边界情况的处理
-
问题描述:
-
容易忽略数组为空或者只有一个元素的特殊情况。对于空数组,不确定应该返回什么结果;对于单个元素的数组,可能没考虑到它其实是满足单调条件的特殊情况。
-
在遍历数组进行比较时,可能出现索引越界错误,比如没有正确处理循环的起始和结束索引。
-
解决办法:
-
针对空数组和单元素数组的情况,在代码开头添加明确的判断逻辑。对于空数组,一般可根据题目要求或约定俗成的规则(通常认为空数组满足单调条件,返回 True )来处理,如下:
def isMonotonic(nums): if len(nums) == 0: return True if len(nums) <= 1: return True increasing = True 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 increasing or decreasing
- 在遍历数组时,要确保索引在有效范围内。如上述代码中,循环是从索引1开始到数组长度结束( for i in range(1, len(nums)) ),这样就避免了对第一个元素(索引0)进行无效的前一个元素比较,同时也不会出现索引越界的问题。
困难三:代码逻辑的简洁性和正确性平衡
- 问题描述:
- 可能一开始会写出比较复杂、冗长的代码来实现判断单调的功能。比如,可能会分别用两个独立的循环来判断单调递增和单调递减情况,或者使用过多的条件分支语句,使得代码可读性差且容易出错。
- 解决办法:
- 在有了初步的代码思路后,停下来思考是否有更简洁高效的实现方式。比如上述示例代码,通过同时维护两个布尔变量来综合判断单调的可能性,避免了重复的遍历和复杂的逻辑嵌套,最后通过一个简单的逻辑或运算得出结果,大大提高了代码的简洁性和可读性。
- 参考一些优秀的代码示例、算法教程或在网上搜索相关的代码实现思路,学习别人是如何用简洁的方式解决类似问题的,然后结合自己的理解对代码进行优化。例如,可以对比以下两种不同的实现方式:
复杂实现方式示例(不推荐):
def isMonotonicComplex(nums):
is_increasing = True
is_decreasing = True
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
if nums[j] > nums[i]:
is_decreasing = False
elif nums[j] < nums[i]:
is_increasing = False
return is_increasing or is_decreasing
这个代码使用了两层循环来比较数组中的每一对元素,判断是否单调,虽然能实现功能,但代码复杂且效率较低。
简洁实现方式示例(推荐):
def isMonotonic(nums):
if len(nums) <= 1:
return True
increasing = True
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 increasing or decreasing
通过对比可以明显看出,简洁实现方式在保证正确性的同时,代码更加清晰易懂,执行效率也更高。所以在编写代码时,要多思考如何优化逻辑,使其既简洁又正确。