题目分析
我们的问题是将一个数组中的所有正整数变为0,最小化删除数字所需的步数。每次操作允许删除一个数的任意一位。
解题思路
-
删除数字的本质
- 每个数字有 ( \text{len}(num) ) 个字符,将其逐步删除为 0 的过程需要 ( \text{len}(num) ) 步。
- 对于一个数组中的所有数字,总步数就是所有数字的位数之和。
-
如何计算最小步数
- 遍历数组中的每个数字,将其转换为字符串,计算字符串的长度,累加到总步数中。
-
优化点
- 数字的位数可通过对每个数字直接使用字符串长度 ( \text{len}(num) ),无需逐位操作。
-
算法复杂度
- 时间复杂度:( O(n \cdot k) ),其中 ( n ) 是数组长度,( k ) 是数字的平均位数。
- 空间复杂度:( O(1) ),只需记录总步数的变量。
代码实现
以下是 C++ 实现:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// 求解最少步数
int solution(int n, vector<int>& a) {
int total_steps = 0; // 总步数
// 遍历数组中的每个数字
for (int num : a) {
// 将数字转为字符串,并累加位数
string num_str = to_string(num);
total_steps += num_str.size(); // 每位都需要一步删除
}
return total_steps;
}
int main() {
// 测试用例
vector<int> a1 = {10, 13, 22, 100, 30};
cout << solution(5, a1) << endl; // 输出:7
vector<int> a2 = {5, 50, 505};
cout << solution(3, a2) << endl; // 输出:4
vector<int> a3 = {1000, 1, 10, 100};
cout << solution(4, a3) << endl; // 输出:4
return 0;
}
代码解析
-
核心逻辑
- 使用
to_string(num)将数字转为字符串,获取字符串的长度(即数字的位数)。 - 每个数字的位数累加到总步数中。
- 使用
-
关键点
- 数字转换为字符串可以直接获取位数,而不需要逐位操作或除法。
- 总步数是简单的累加过程,无需复杂的条件判断。
测试结果
示例 1
- 输入:( n = 5, a = [10, 13, 22, 100, 30] )
- 解析:
- 10 → 2 位
- 13 → 2 位
- 22 → 2 位
- 100 → 3 位
- 30 → 2 位
- 总步数:( 2 + 2 + 2 + 3 + 2 = 7 )
- 输出:7
示例 2
- 输入:( n = 3, a = [5, 50, 505] )
- 解析:
- 5 → 1 位
- 50 → 2 位
- 505 → 3 位
- 总步数:( 1 + 2 + 3 = 4 )
- 输出:4
示例 3
- 输入:( n = 4, a = [1000, 1, 10, 100] )
- 解析:
- 1000 → 4 位
- 1 → 1 位
- 10 → 2 位
- 100 → 3 位
- 总步数:( 4 + 1 + 2 + 3 = 10 )
- 输出:10
总结
-
方法概述
- 遍历数组,逐个统计数字的位数并累加。
- 时间复杂度低,易于实现。
-
应用场景
- 适用于需要统计或操作数字字符数的问题。
-
优化潜力
- 数字位数可以直接通过数学计算 ( \text{floor}(\log_{10}(\text{num}) + 1) ) 获取,避免字符串转换。