45.最少步数归零问题
-
问题描述
小R拿到了一个长度为n的数组,其中每个元素都是一个正整数。小R发现每次可以删除某个数组中某个数的一位数字,这样可以逐步将所有数字变为0。他想知道,要将数组中所有数字都变为0,最少需要多少步?
例如:对于数字 103,小R可以选择删除第1位数字,将其变为 3;或者删除第2位数字,变为 13,又或者删除第3位数字,将其变为 10。最终目标是将所有数字都删除为0。
-
思路解析
1.删除数字的规则:每次可以删除某个数字的一位。
2.目标:将数组中的所有数字都变为0。 -
数据结构的选择
由于我们需要处理的是一个数组,并且每次操作是对数组中的每个数字进行删除一位的操作,因此我们可以直接使用数组来存储这些数字。
-
解题步骤
1.初始化步骤计数器:用于记录总共需要的步骤数。
2.循环处理数组:- 每次循环中,找到数组中最小的非零数字。
- 对数组中的每个数字进行删除一位的操作。
- 如果某个数字变为0,则将其标记为0。
- 更新步骤计数器:每次循环结束后,步骤计数器加1。
- 终止条件:当数组中所有数字都变为0时,终止循环。
-
关键点
- 删除一位的操作:如何高效地删除数字的一位?可以通过整除和取模操作来实现。
- 最小数字的选择:每次循环中选择最小的非零数字,这样可以确保每次删除操作都是最有效的。
-
关键步骤
- 删除数字的一位:在每次循环中,使用
min(num for num in a if num > 0)来找到数组中最小的非零数字。这样可以确保每次删除操作都是最有效的。 - 查找最小非零数字:在每次循环中,使用
min(num for num in a if num > 0)来找到数组中最小的非零数字。这样可以确保每次删除操作都是最有效的。 - 更新数组:使用列表推导式
[remove_digit(num) if num > 0 else 0 for num in a]来更新数组中的每个数字。如果某个数字变为0,则将其标记为0。 - 更新步骤计数器:每次循环结束后,步骤计数器
steps加1。
- 删除数字的一位:在每次循环中,使用
-
代码
def solution(n: int, a: list) -> int:
def remove_digit(num):
res = 0
power = 1
while num > 0:
res += (num // 10) * power
num //= 10
power *= 10
return res
steps = 0
while any(a):
min_num = min(a)
a = [remove_digit(num) if num > 0 else 0 for num in a]
steps += 1
return 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)