以下为题目描述
问题描述
数字魔法师小U发现了一种特殊的数字变换魔法。这个魔法可以对一个数字字符串进行"进位"操作。每次操作规则如下:
- 对字符串中的每个数字进行加一操作
- 当某位数字为9时,加一后变成 0,并在前面补 1
例如:
- "798" 经过一次操作变成 "8109"(7→8, 9→0并向前增加一个1, 8→9)
- "999" 经过一次操作变成 "101010"
现在给定一个数字字符串 num_str(长度为n)和操作次数 k,请计算经过 k 次操作后得到的最终结果。由于结果可能非常大,请将答案对 1000000007 (10^9 + 7) 取模。
输入
- 第一行包含两个整数 n 和 k(1 ≤ n ≤ 50, 1 ≤ k ≤ 100)
- 第二行包含一个长度为n的数字字符串 num_str,仅由数字0-9组成
返回
- 返回一个整数,表示最终结果对 1000000007 取模后的值
测试样例
样例1:
输入:
n = 3 ,k = 1 ,num_str = "798"
返回:8109
解释:798 经过一次操作变成 8109
样例2:
输入:
n = 3 ,k = 3 ,num_str = "798"
返回:103221
- 第一次操作:798 → 8109
- 第二次操作:8109 → 92110
- 第三次操作:92110 → 103221
样例3:
输入:
n = 4 ,k = 3 ,num_str = "7989"
返回:10322132
解决方案
public class Main {
public static int solution(int n, int k, String num_str) {
final int MOD = 1000000007;
StringBuilder currentNumber = new StringBuilder(num_str);
for (int op = 0; op < k; op++) {
StringBuilder newNumber = new StringBuilder();
int length = currentNumber.length();
for (int i = 0; i < length; i++) {
char ch = currentNumber.charAt(i);
if (ch == '9') {
// 数字为 '9',加一后变成 '0',并在前面补 '1'
newNumber.append('1');
newNumber.append('0');
} else {
// 数字加一操作
char incrementedDigit = (char) (ch + 1);
newNumber.append(incrementedDigit);
}
}
currentNumber = newNumber;
}
// Convert the final number to integer modulo MOD
String finalNumberStr = currentNumber.toString();
int result = 0;
for (int i = 0; i < finalNumberStr.length(); i++) {
result = (int) ((result * 10L + (finalNumberStr.charAt(i) - '0')) % MOD);
}
return result;
}
public static void main(String[] args) {
// You can add more test cases here
System.out.println(solution(3, 1, "798") == 8109);
System.out.println(solution(3, 3, "798") == 103221);
}
}
代码解释
- 执行 k 次操作
for (int op = 0; op < k; op++) {
StringBuilder newNumber = new StringBuilder();
int length = currentNumber.length();
for (int i = 0; i < length; i++) {
char ch = currentNumber.charAt(i);
if (ch == '9') {
// 数字为 '9',加一后变成 '0',并在前面补 '1'
newNumber.append('1');
newNumber.append('0');
} else {
// 数字加一操作
char incrementedDigit = (char) (ch + 1);
newNumber.append(incrementedDigit);
}
}
// 更新当前数字为新生成的数字
currentNumber = newNumber;
}
• 外层循环执行 k 次操作。
• 内层循环遍历当前数字字符串的每一位,对每个字符进行判断和处理:
1)如果字符为 '9' :
(1)根据规则,将 '9' 加一后变成 '0',并在前面补 '1'
(2)具体操作是先 append('1'),再 append('0'),即将 '9' 变成 '10'
2)如果字符不是 '9' :
(1)将字符的 ASCII 码值加一,得到加一后的字符
(2)例如,字符 '7' 加一后变成 '8'
(3)完成一次操作后,更新 currentNumber 为新生成的数字字符串,为下一次操作做准备
- 将最终的数字字符串转换为整数并取
String finalNumberStr = currentNumber.toString();
int result = 0;
for (int i = 0; i < finalNumberStr.length(); i++) {
result = (int) ((result * 10L + (finalNumberStr.charAt(i) - '0')) % MOD);
}
return result;
• 将 currentNumber 转换为字符串 finalNumberStr
• 使用 result 来存储最终的结果,初始化为 0
• 遍历 finalNumberStr 的每一位,将其转换为数字,并按照高精度计算的方法,逐位构造数字,同时在每一步都取模,防止溢出
(1)result * 10L:将当前结果左移一位(乘以 10)
(2)finalNumberStr.charAt(i) - '0':将字符转换为对应的数字
(3)result = (result * 10L + digit) % MOD:更新结果并取模