45. 最小步数归零问题解题思路 | 豆包MarsCode AI刷题

86 阅读3分钟

题目分析

题目要求计算最少的步数,使得数组中每个数字都变为 0。每步操作可以删除某个数字的一位,目标是最小化步骤数,最终所有数字都变为 0。

解题思路

1. 问题的核心

每次删除一位数字,并且每个数字变为 0 的过程最终是通过多次删除操作完成的。那么最少的删除操作次数实际上是与数字中非零的位数相关的。因为:

  • 如果一个数字中某个位置是 0,则该位置无需删除;
  • 如果某个位置是非零数(即 1-9),则该位置的数字需要在某个时刻删除。

2. 逐步分析

  • 首先,对于每个数字,我们需要计算它的非零数字的个数。比如:

    • 103 中有两个非零数字:1 和 3;
    • 500 中有一个非零数字:5;
    • 2000 中有一个非零数字:2。
  • 然后我们将所有数字的非零位数加起来,得到最少的删除步数。

3. 时间复杂度

  • 对于每个数字,将它转化为字符串,然后遍历字符串中的每个字符,判断是否为 0。对于长度为 m 的数字,最多需要 O(m) 的时间来计算非零数字的个数。
  • 所以,整个算法的时间复杂度为 O(n * m),其中 n 是数组的长度,m 是数字的最大位数。这个复杂度是可以接受的。

解题步骤

  1. 遍历数组:对于数组中的每一个数字,将其转换为字符串形式。
  2. 计算非零数字的个数:遍历字符串中的每个字符,统计非零字符的个数。
  3. 累加所有数字的非零位数:将每个数字的非零位数相加,得到最终的最小删除步数。
  4. 输出结果

代码实现

public static int solution(int n, int[] a) {
    int totalSteps = 0; // 用于累加总步数

    // 遍历数组中的每个数字
    for (int num : a) {
        // 将数字转换为字符串并计算其长度
        String s = String.valueOf(num);
        int cnt = 0;
        
        // 遍历每个字符,如果不是 '0',则该位是有效的非零位
        for (char c : s.toCharArray()) {
            if (c != '0') {
                cnt++; // 如果该字符不是0,非零位数加1
            }
        }
        
        // 将当前数字的非零位数累加到总步数
        totalSteps += cnt;
    }

    // 返回总步数
    return totalSteps;
}

详细步骤:

  1. 遍历数字:我们首先遍历数组中的每个数字,for (int num : a),对于每一个数字,我们将其转换成字符串 String s = String.valueOf(num),这样我们可以方便地逐位检查每个数字。
  2. 计算非零位数:对于数字中的每一位,我们判断它是否是 0。如果不是 0,那么就算作一步有效的删除操作。使用 for (char c : s.toCharArray()) 来遍历数字的每一位,如果该字符不等于 '0',就将 cnt 加一。
  3. 累加步数:对每个数字的非零位数 cnt 进行累加,最终得到所有数字需要的最小删除步数。
  4. 返回结果:返回最终累加的步数 totalSteps,即为最小操作步数。