题目:最少步数归零问题
题目描述
小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
- 输入:
解题思路
-
理解问题:每个数字可以删除任意一位,直到变为0。我们需要计算将所有数字变为0所需的最少步数。
-
数据结构选择:将每个数字转换为字符串,这样更容易处理每一位的删除操作。
-
算法步骤:
- 遍历数组中的每个数字。
- 将每个数字转换为字符串。
- 计算每个字符串的长度,因为每个字符串的长度就是将其变为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),用于存储字符串。