45.最少步数归零问题 题目解析 | 豆包MarsCode AI刷题

34 阅读2分钟

题目:最少步数归零问题

题目描述

小R拿到了一个长度为n的数组,其中每个元素都是一个正整数。小R发现每次可以删除某个数组中某个数的一位数字,这样可以逐步将所有数字变为0。他想知道,要将数组中所有数字都变为0,最少需要多少步?

例如:对于数字 103,小R可以选择删除第1位数字,将其变为 3;或者删除第2位数字,变为 13,又或者删除第3位数字,将其变为 10。最终目标是将所有数字都删除为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

解题思路

  1. 理解问题:每个数字可以删除任意一位,直到变为0。我们需要计算将所有数字变为0所需的最少步数。

  2. 数据结构选择:将每个数字转换为字符串,这样更容易处理每一位的删除操作。

  3. 算法步骤

    • 遍历数组中的每个数字。
    • 将每个数字转换为字符串。
    • 计算每个字符串的长度,因为每个字符串的长度就是将其变为0所需的最少步数。
    • 累加所有字符串的长度,得到最终结果。

实现代码

#include <iostream>
#include <vector>
#include <string>
using namespace std;

int solution(int n, vector<int>& a) {
    int totalDigits = 0;  
    int zeroCount = 0;   
    for (int num : a) {
        string numStr = to_string(num);
        totalDigits += numStr.length();
        for (char digit : numStr) {
            if (digit == '0') {
                zeroCount++;
            }
        }
    }
    return totalDigits - zeroCount;
}
int main() {
    vector<int> a1 = {10, 13, 22, 100, 30};
    cout << (solution(5, a1) == 7) << endl;

    vector<int> a2 = {5, 50, 505};
    cout << (solution(3, a2) == 4) << endl;

    vector<int> a3 = {1000, 1, 10, 100};
    cout << (solution(4, a3) == 4) << endl;
}

总结

这个问题的关键在于理解每个数字的非零位数决定了将该数字变为0所需的最小操作次数。通过逐位检查每个数字并统计非零数字的数量,我们可以高效地解决这个问题。

  • 关键点:将数字转换为字符串,统计字符串的长度(即位数),累加所有字符串的长度即为最少步数。
  • 优化点:无需考虑数字0的个数,因为每个数字的位数已经包含了所有需要删除的步数。
  • 复杂度:时间复杂度为O(n * m),其中n是数组的长度,m是数字的最大位数。空间复杂度为O(m),用于存储字符串。