解题代码参考来源:优化版竖式
- 问题描述
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
示例 1: 输入: num1 = “2”, num2 = “3” 输出: “6”
示例 2: 输入: num1 = “123”, num2 = “456” 输出: “56088”
说明:num1 和 num2 的长度小于110。num1 和 num2 只包含数字 0-9。num1 和 num2 均不以零开头,除非是数字 0 本身。不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/multiply-strings - 分析
刚开始想的是,用类似于“加法器”的做法,分别用两个数组保存来保存这两个数的各个数位,每次从两个数组的最后面进行一位一位的乘法计算。然后再用两个数组,一个数组保存结果的各个数位,一个数组保存进行一位一位的乘法计算的进位。像这样一位一位计算虽然简化了,但是对于结果中间的数位是两个数的中间某几位(具体位数又要根据实际情况判断)的运算结果叠加,这样做很麻烦。
后来参考leetcode上面大佬的解法:https://leetcode-cn.com/problems/multiply-strings/solution/you-hua-ban-shu-shi-da-bai-994-by-breezean/。发现思想和大佬的差不多,都是一位一位计算。大佬用两个元素表示结果,因为一位数乘一位数最大是两位数,但其实这两位有一位就是进位。我没想到的是通过双重循环过程中自然而然的解决了关于结果的中间数位的叠加求解。我一直想通过叠加一次性把结果的最终数位求出来,但是忽略了用每一个数位计算是要用双循环进行遍历的,而在循环过程中就自然而然的叠加出来了。 - 代码
class Solution {
public String multiply(String num1, String num2) {
//乘数为0返回0
if ("0".equals(num1) || "0".equals(num2)) {
return "0";
}
//结果最大位数为num1.length() + num2.length()
int[] res = new int[num1.length() + num2.length()];
for (int i = num1.length() - 1; i >= 0; i--) {
//得到第i个位置字符所代表的数字,这里的计算是用ASCII码
int n1 = num1.charAt(i) - '0';
for (int j = num2.length() - 1; j >= 0; j--) {
int n2 = num2.charAt(j) - '0';
int sum = (res[i + j + 1] + n1 * n2);
//保存结果的个位,注意叠加
res[i + j + 1] = sum % 10;
//保存结果的十位(也就是进位),注意叠加
res[i + j] += sum / 10;
}
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < res.length; i++) {
//由于最高位的进位即使是0也保存下来了的,故要去除
if (i == 0 && res[i] == 0) {
continue;
}
result.append(res[i]);
}
return result.toString();
}
}
2019.12.03