一 题目
Given two non-negative integers num1
and num2
represented as strings, return the product of num1
and num2
, also represented as a string.
Example 1:
Input: num1 = "2", num2 = "3"
Output: "6"
Example 2:
Input: num1 = "123", num2 = "456"
Output: "56088"
Note:
- The length of both
num1
andnum2
is < 110. - Both
num1
andnum2
contain only digits0-9
. - Both
num1
andnum2
do not contain any leading zero, except the number 0 itself. - You must not use any built-in BigInteger library or convert the inputs to integer directly.
二 分析
求两个数的乘积,限制了直接转换位integer操作,medium级别难度,之前做过一个除法 leetcode 29. Divide Two Integers
这个乘法本来想试试。
public static String multiply(String num1, String num2) {
//conercase
if(num1.equals("0")|| num2.equals("0")){
return "0";
}
//转换为数字
Double n1=0d;
for(int i=0;i<num1.length();i++){
n1=n1+ Math.pow(10, num1.length()-1-i ) *(num1.charAt(i)-'0') ;
}
Double n2 = 0d;
for(int i=0;i<num2.length();i++){
n2=n2+ Math.pow(10, num2.length()-1-i ) *(num2.charAt(i)-'0') ;
}
return String.valueOf(n1 * n2) ;
}
很快就会放弃了,因为case例子超过了integer、long的限制。如:"498828660196","840477629533"。题目的限制是长度《110.
看了下讨论区的解决方法,居然是回到了小学的时候多位数乘法,错位相加的办法。没有什么骚操作,真是不忘初心啊。
只靠朴素的理解按位相乘错位相加是不够的。还要找规律:
- 1 .num1 长度为m,num2 长度为n,则 num1 x num2 的长度不会超过 m+n。2
- 2. 作者画图是想说明,num1 和 num2 中任意位置的两个数字相乘,得到的两位数在最终结果中的位置是确定的,比如 num1 中位置为i的数字乘以 num2 中位置为j的数字,那么得到的两位数(个位数相乘结果可能为0-81)字的位置为 i+j 和 i+j+1
`num1[i] * num2[j]` will be placed at indices `[i + j`, `i + j + 1]`
还是从个位开始,从低往高计算。对应的遍历顺序就是 num1 和 num2 字符串的尾部开始往前遍历。 某一位的计算还是要转换为数字再相乘。 然后根据上面的规律确定相乘后的两位数所在的位置 p1 和 p2,把乘积放到对应的位置,要先从个位p2开始放,还要考虑到+p2后进位的情况。
最后是是吧结果pos从高往低输出。要注意过滤掉开头的“0”
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println( multiply("498828660196","840477629533") );
}
public static String multiply(String num1, String num2) {
if(num1.equals("0")||num2.equals("0")){
return "0";
}
int m = num1.length(), n = num2.length();
//规律发现,相乘的长度不会超过m+n
int[] pos = new int[m + n];
//从低位到高位遍历
for(int i=m-1;i>=0;i--){
for(int j=n-1;j>=0;j--){
int tmp = (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
//这里就是图上的规律,吧乘积放到对应位置
int p1 = i+j; int p2 =i+j+1;
//先加个位的数字
int sum = tmp + pos[p2];
//考虑进位的情况:
pos[p1] += sum / 10;
//进位后剩余的个位
pos[p2] = (sum) % 10;
}
}
StringBuilder sb = new StringBuilder();
//从高位开始输出结果
for(int i=0; i<pos.length; i++){
//过滤掉开头的0
if(sb.length() == 0 && pos[i] == 0){
continue;
}
sb.append(pos[i]);
}
return sb.toString();
}
Runtime: 4 ms, faster than 86.79% of Java online submissions for Multiply Strings.
Memory Usage: 36.1 MB, less than 100.00% of Java online submissions for Multiply Strings.
真心佩服大神们。自己真心做不出来啊。