递归法解题
最少步数归零问题
1.问题描述
小R拿到了一个长度为n的数组,其中每个元素都是一个正整数。小R发现每次可以删除某个数组中某个数的一位数字,这样可以逐步将所有数字变为0。他想知道,要将数组中所有数字都变为0,最少需要多少步?
例如:对于数字 103,小R可以选择删除第1位数字,将其变为 3;或者删除第2位数字,变为 13,又或者删除第3位数字,将其变为 10。最终目标是将所有数字都删除为0。
2.测试样例
样例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
3.题目思路
通过递归深度优先搜索的方式,对每个数字尝试所有可能的删除位操作,计算出将每个数字变为0所需的最少步数,并将这些步数累加,以得到将数组中所有数字变为0所需的总最少步数。
4.详细方法
deleteSteps 函数:
- 基本情况:
如果 num 为 0,则不需要任何步骤,返回 0。
如果 num 是一位数,那么只需要一步就可以将其变为 0,返回 1。
- 递归情况:
对于每一位数字,我们考虑删除该位数字后的情况。将 num 转换为字符串 num_str,以便可以操作每一位数字。遍历 num_str 的每一位数字,对于当前索引 i,我们构造一个新的数字 new_num,它是删除了第 i 位数字后的数字。
- 递归调用:
对于每个 new_num,我们递归地调用 deleteSteps 函数,计算将其变为 0 所需的最少步数。
- 结果更新:
我们维护一个变量 res,初始值为正无穷大 float('inf'),表示当前找到的最小步数。对于每个 new_num,我们计算删除当前位数字后,剩余数字变为 0 所需的最少步数,并更新 res 为当前找到的最小值。
- 返回结果:
最后,返回 res + 1,因为当前位数字也被删除了,所以需要额外加一步。
solution 函数:
- 初始化:
total_steps 初始化为 0,用于累加所有数字变为 0 所需的总步数。
- 遍历数组:
遍历输入数组 a 中的每个数字 num。
- 累加步数:
对于每个 num,调用 deleteSteps 函数计算将其变为 0 所需的最少步数,并累加到 total_steps。
- 返回结果:
最后,返回 total_steps,即数组中所有数字变为 0 所需的总步数。
5.代码实现
def deleteSteps(num):
# 将数字转换为字符串,方便操作每一位数字
num_str = str(num)
if num == 0:
return 0
if len(num_str) == 1:
return 1
# 删除每一位数字后,剩余数字变为0所需的最少步数
res = float('inf')
for i in range(len(num_str)):
# 删除当前位数字后,剩余数字
new_num = int(num_str[:i] + num_str[i+1:])
# 计算删除当前位数字后,剩余数字变为0所需的最少步数
res = min(res, deleteSteps(new_num) + 1)
return res
def solution(n: int, a: list) -> int:
total_steps = 0
for num in a:
total_steps += deleteSteps(num)
return total_steps
if __name__ == '__main__':
print(solution(5, [10, 13, 22, 100, 30]) == 7)
print(solution(3, [5, 50, 505]) == 4)
print(solution(4, [1000, 1, 10, 100]) == 4)