判断数组是否单调及AI刷题实践 | 豆包MarsCode AI刷题

41 阅读5分钟

问题描述

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

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

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

解题思路

  1. 初始化标志:我们可以使用两个布尔变量来分别表示数组是否是单调递增或单调递减。
  2. 遍历数组:从第二个元素开始,逐个比较当前元素和前一个元素。
  3. 更新标志
    • 如果当前元素大于前一个元素,则数组可能是单调递增的。
    • 如果当前元素小于前一个元素,则数组可能是单调递减的。
    • 如果当前元素等于前一个元素,则继续检查下一个元素。
  4. 判断结果:如果在遍历过程中,发现既不符合单调递增也不符合单调递减的条件,则数组不是单调数组。

代码人生

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
        
        # 如果既不是单调递增也不是单调递减,提前返回
        if not is_increasing and not is_decreasing:
            return False
    
    # 如果遍历完数组,仍然符合单调递增或单调递减的条件
    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_increasingis_decreasing 用于记录数组是否可能是单调递增或单调递减。
  • 遍历数组:从第二个元素开始,逐个比较当前元素和前一个元素。
  • 更新标志:根据比较结果更新 is_increasingis_decreasing
  • 提前返回:如果在遍历过程中发现数组既不是单调递增也不是单调递减,则直接返回 False
  • 最终返回:如果遍历完数组后,is_increasingis_decreasing 仍然为 True,则返回 True

测试样例

样例1:

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

样例2:

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

样例3:

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

Marscode AI刷题实践

代码可改进之处:

  1. 测试用例的使用方式

    • 在 if __name__ == '__main__': 部分,目前是直接在 print 语句中调用 solution 函数并比较其返回值与预期值是否相等,然后打印出比较结果(True 或 False)。这种方式虽然可以直观地看到每次测试用例的执行结果是否符合预期,但如果要进行大量测试用例的测试或者需要更详细的测试报告(比如记录每个测试用例的输入、输出以及是否通过测试等信息),这种方式就不太方便了。可以考虑使用 Python 标准库中的 unittest 模块或者 pytest 等测试框架来更规范地组织和执行测试用例,这样能使测试过程更加灵活、可扩展且便于维护。
  2. 代码复用性

    • 目前代码是针对一个特定的 solution 函数进行测试,如果后续还有其他类似的函数需要进行测试,就需要重复编写类似的测试代码。可以将测试相关的代码封装成一个独立的测试函数或者测试类,通过传入不同的函数和测试用例数据来实现对不同函数的测试,提高代码的复用性。
  3. 输入验证

    • 代码没有对输入的 nums 参数进行有效性验证。如果传入的 nums 不是一个列表类型,或者是一个空列表,可能会导致代码出现意外的行为(比如空列表在当前逻辑下会被误判为单调数组,因为循环体不会被执行,直接返回 True)。可以在函数开头添加一些输入验证的逻辑,比如判断 nums 是否为列表类型以及是否为空,若不符合要求则抛出相应的异常或者返回特定的错误提示值。

以下是一个使用 unittest 模块改进测试部分的示例代码(假设上述 solution 函数所在的文件名为 monotonic_array.py):

import unittest
from monotonic_array import solution


class TestMonotonicArray(unittest.TestCase):
    def test_monotonic_array(self):
        self.assertEqual(solution(nums=[1, 2, 2, 3]), True)
        self.assertEqual(solution(nums=[6, 5, 4, 4]), True)
        self.assertEqual(solution(nums=[1, 3, 2, 4, 5]), False)


if __name__ == '__main__':
    unittest.main()

在上述改进后的代码中,通过使用 unittest 模块创建了一个测试类 TestMonotonicArray,并在其中定义了一个测试方法 test_monotonic_array,在该方法中使用 self.assertEqual 语句来规范地对 solution 函数的不同测试用例进行测试。最后通过 if __name__ == '__main__': 部分调用 unittest.main() 来执行所有的测试用例,这样可以更方便地管理和扩展测试用例,并且能得到更清晰的测试报告。