给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
示例 1:
输入: num1 = “2”, num2 = “3”
输出: “6”
示例 2:
输入: num1 = “123”, num2 = “456”
输出: “56088”
这个很简单,只要按照平常的算法来写就行。其实这道题是典型的复杂问题分解简单问题的思路。首先是一个字符和字符串的乘法,然后是字符串的加法。最后是去掉前导0。写出来只是时间问题。
class Solution {
public String multiply(String num1, String num2) {
int num1Len = num1.length();
int num2Len = num2.length();
StringBuilder lastZero = new StringBuilder();
List<String> totalNum = new ArrayList<>();
for (int i = num1Len - 1; i > -1; --i) {
int carry = 0;
StringBuilder sb = new StringBuilder();
sb.append(lastZero);
for (int j = num2Len - 1; j > -1; --j) {
char num1CurCh = num1.charAt(i);
if (num1CurCh == '0') {
sb.append("0");
break;
}
char num2CurCh = num2.charAt(j);
int temp = (num1CurCh - '0') * (num2CurCh - '0') + carry;
if (temp > 9) {
sb.insert(0, temp % 10);
carry = temp / 10;
} else {
sb.insert(0, temp);
carry = 0;
}
}
if (carry != 0) {
sb.insert(0, carry);
}
lastZero.append("0");
totalNum.add(sb.toString());
}
String ret = "";
for (String num : totalNum) {
ret = plusStr(ret, num);
}
// 去掉前导0
int idx;
for (idx = 0; idx < ret.length(); ++idx) {
if (ret.charAt(idx) != '0') {
break;
}
}
if (idx == ret.length()) {
ret = "0";
} else {
ret = ret.substring(idx);
}
return ret;
}
public String plusStr(String s1, String s2) {
if (s1.length() < s2.length()) {
return plusStr(s2, s1);
}
int s1Len = s1.length();
int subVal = s1Len - s2.length();
int carry = 0;
StringBuilder sb = new StringBuilder();
for (int i = s1Len - 1; i > -1; --i) {
char s1CurCh = s1.charAt(i);
if (i - subVal >= 0) {
char s2CurCh = s2.charAt(i - subVal);
int temp = Integer.parseInt(s1CurCh + "") + Integer.parseInt(s2CurCh + "") + carry;
if (temp > 9) {
sb.insert(0, temp % 10);
carry = temp / 10;
} else {
sb.insert(0, temp);
carry = 0;
}
} else {
if (carry != 0) {
int temp = Integer.parseInt(s1CurCh + "") + carry;
if (temp > 9) {
sb.insert(0, temp % 10);
carry = temp / 10;
} else {
sb.insert(0, temp);
carry = 0;
}
} else {
sb.insert(0, s1.substring(0, i + 1));
break;
}
}
}
if (carry != 0) {
sb.insert(0, carry);
}
return sb.toString();
}
}
上面的写法比较垃圾,下面C++写法才是神啊!
class Solution {
public:
string multiply(string num1, string num2) {
int n1 = num1.size(), n2 = num2.size();
string ans(n1 + n2, '0');
for(int i = n1 - 1; i >= 0; i--) {
for(int j = n2 - 1; j >= 0; j--) {
int temp = (ans[i + j + 1] - '0') + (num1[i] - '0') * (num2[j] - '0');
ans[i + j + 1] = temp % 10 + '0';
ans[i + j] += temp / 10;
}
}
for(int i = 0; i < n1 + n2; i++) {
if (ans[i] != '0') return ans.substr(i);
}
return "0";
}
string Plus(string s1, string s2) {
int remain = 0;
int s1Idx = s1.length() - 1;
int s2Idx = s2.length() - 1;
string ret = "";
do {
int s1Num = s1Idx >= 0 ? s1[s1Idx] - '0' : 0;
int s2Num = s2Idx >= 0 ? s2[s2Idx] - '0' : 0;
int sum = s1Num + s2Num + remain;
ret.insert(0, to_string(sum % 10));
remain = sum / 10;
--s1Idx;
--s2Idx;
} while (remain != 0 || (s1Idx >= 0 && s2Idx >= 0));
if (s1Idx >= 0) {
ret.insert(0, s1.substr(0, s1Idx + 1));
}
if (s2Idx >= 0) {
ret.insert(0, s2.substr(0, s2Idx + 1));
}
return ret;
}
};