浅析最小步数归零问题 | 豆包MarsCode AI 刷题

108 阅读3分钟

在练题过程中,我发现了一个比较有意思的题目,就是这个“最小步数归零问题”,题目描述为:小R拿到了一个长度为n的数组,其中每个元素都是一个正整数。小R发现每次可以删除某个数组中某个数的一位数字,这样可以逐步将所有数字变为0。他想知道,要将数组中所有数字都变为0,最少需要多少步?我们先看所给的例子:对于数字 103,小R可以选择删除第1位数字,将其变为 3;或者删除第2位数字,变为 13,又或者删除第3位数字,将其变为 10。最终目标是将所有数字都删除为0。由此来看,要得到将所给数组归零的最少步数的关键在于如何处理数组中已有的0,我们再看样例:

  • 样例1: 输入:n = 5,a = [10, 13, 22, 100, 30] 输出:7

  • 样例2: 输入:n = 3,a = [5, 50, 505] 输出:4

  • 样例3: 输入:n = 4,a = [1000, 1, 10, 100] 输出:4

    联系样例的输入和输出,不难发现,我们只需统计数组中所有元素的非零数字个数就能解决问题,那么反过来我们先计算出数组中所有数字的总位数,再统计出“0”的位数,用总位数减去“0”的位数,也能解决问题,显然后者更容易用代码实现。在前面的笔记也许我也跟大家讲过,用AI的刷题的好处就是你可以把她当做一个助手,和它讨论思路,完善代码,现在我想给大家展示一下我和AI的探讨之旅。

首先,我让AI给我一个代码的大致框架,其给出的结果是这样的:

def solution(n: int, a: list) -> int:
    # 初始化步数为0
    steps = 0
    
    # 遍历数组中的每个数字
    for num in a:
        # 计算当前数字的位数
        # 提示:可以使用字符串长度来计算位数
        num_digits = len(str(num))
        
        # 累加步数
        steps += num_digits
    
    # 返回总步数
    return steps

上述代码实现了统计出数组中所有数字的位数和,但没有考虑“0”的问题,显然是不完善的,不能真正解决问题,于是我又提示她,如果数组元素中每出现一个零,实现归零时所需的步数是减1的,她说我是对的,就给出完善的代码:

 # 检查当前数字是否包含0
        if '0' in str(num):
            # 如果包含0,步数减1
            steps -= 1

其实这也有问题,如果某一个元素使“100”,正确的应该是步数减2,但如果用上述代码实现就只会减1,那么到这里我们不妨自己想想如何进一步去完善它呢?也许很容易想到在Python中用find函数可以找到任意元素,而用count函数就可以统计某一元素的个数,所以我们可以这样改:

# 检查当前数字是否包含0,并统计0的个数,可以使用字符串的count方法来统计0的个数
        zero_count = str(num).count('0')
        
        # 如果包含0,步数减去0的个数
        steps -= zero_count

这样我们就能完全地解决这个问题了!我的笔记就到这里,如有纰漏,还请指正!