先看一下在 leetcode 上的执行结果:
可以看到,这里有空间换时间的问题
原题
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
说明:
num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/multiply-strings
思路
我们模仿手工乘法的过程,也就是将竖乘的过程程序化
- 两个数 num1 和 num2 从低位到高位记序为0,1,2…时(比如5429中,9为第0位,2为第1位,4位第2位),若 num1 位于第 i 位的数与 num2 位于第 j 位的数相乘结果位于最终结果的第 i+j 位(先不考虑进位问题)
- 我们先不考虑进位问题,也就是说一开始先进行“没有进位的乘法”,然后再统一进行进位处理
代码
class Solution {
public String multiply(String num1, String num2) {
int n1 = num1.length()-1; //从0开始计数,所以用长度减1会方便些
int n2 = num2.length()-1;
if(n1<0 || n2<0)
return ""; //处理输入为空的特殊情况
if(num1.equals("0") || num2.equals("0"))
return "0"; //若不加这一块,乘以“0”会出现“0000”这样的结果,而不是“0”
int[] ans = new int[n1+n2+2]; //两数相乘,长度最长为两数各自长度的乘积
for(int i = 0;i<n1+1;i++)
for(int j = 0;j<n2+1;j++ ){
int n = i + j;
ans[n] += (num1.charAt(n1-i)-'0')*(num2.charAt(n2-j)-'0');
}
/*在字符串中,最左侧为0位,但我们想让最右边为0位,故用n1-i,而不是i*/
for(int t = 1;t<n1+n2+2;t++){ //这个循环用来处理进位问题
ans[t] += ans[t-1]/10;
ans[t-1] = ans[t-1]%10;
}
//用len处理可能存在的位于高位的多余的0
int len = ans[n1+n2+1] == 0?n1+n2:n1+n2+1;
StringBuilder sb = new StringBuilder();
for(int i = len; i>-1; i--)
sb.append(ans[i]);
return sb.toString();
}
}