LeetCode 43字符串相乘
-
题目简述:给定两个以字符串形式表示的非负整数
num1
和num2
,返回num1
和num2
的乘积,它们的乘积也表示为字符串形式。 -
输入:num1 = “2”, num2 = “3” 输出:“6”
输入:num1 = “123”, num2 = “456” 输出:“56088”
-
说明
- num1 和 num2 的长度小于 110。
- num1 和 num2 只包含数字 0-9。
- num1 和 num2 均不以零开头,除非是数字 0 本身。
- 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
-
思路:高精度乘法
模拟乘法竖式运算过程,乘法的最大长度是两个乘数长度之和m+n,时间复杂度是O(nm)
class Solution {
public:
string multiply(string num1, string num2) {
int n = num1.size(), m = num2.size();
vector<int> a(n), b(m), c(n+m);
//数组低位下标对应数字个位,高位下标对应数字高位
for(int i = 0; i < n; i++) a[n - 1 - i] = num1[i] - '0';
for(int j = 0; j < m; j++) b[m - 1 - j] = num2[j] - '0';
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
c[i + j] += a[i] * b[j];
c[i + j + 1] += c[i + j] / 10;
c[i + j] %= 10;
}
}
int l = n + m;
while (l > 1 && c[l - 1] == 0) l--;//去掉前导0
string ans;
for(int i = l - 1; i >= 0; i--)
ans += c[i] + '0';
return ans;
}
};
- 简化写法:
num1[i]
和num[j]
的乘积位置对应c[i+j]
和c[i+j+1]
这两个位置,将低位c[i+j]
的数累加,高位c[i+j+1]
的数取余进位,给下一个高位
class Solution {
public:
string multiply(string num1, string num2) {
int n = num1.size(), m = num2.size();
vector<int> c(n+m);
//从个位开始逐位相乘
for(int i = n - 1; i >= 0; i--)
{
for(int j = m - 1; j >= 0; j--)
{
int mul = (num1[i] - '0')*(num2[j] - '0');
int sum = mul + c[i + j + 1];
c[i + j + 1] = sum % 10;
c[i + j] += sum / 10;
}
}
//去掉前导0
int l = 0;
while (l < c.size() && c[l] == 0) l++;
// 将计算结果转化成字符串
string ans;
for(; l < c.size(); l++)
ans += c[l] + '0';
return ans.size() == 0 ? "0" : ans;
}
};
- 思路二:一开始不考虑进位,直接将每位乘积和存入数组,最后统一处理进位
class Solution {
public:
string multiply(string num1, string num2) {
int n = num1.size(), m = num2.size();
vector<int> c(n+m, 0);
//不考虑进位,直接将每个位乘积存入数组,c[0]存个位乘积,+=累积每位的乘积和
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
c[i + j] += (num1[n - i - 1] - '0') * (num2[m - 1 - j] - '0');
//cout << i << j << c[i + j] << endl;//查看数组每位情况
//统一处理数组进位
for(int i = 0; i < n + m; i++)
{
if(c[i] > 9)//比9大就产生进位
{
int t = c[i];
c[i] = t % 10;
c[i + 1] += (t / 10);
}
}
//去掉前导0
int l = n + m;
while (l > 1 && c[l - 1] == 0) l--;
// 将计算结果转化成字符串
string ans;
for(int i = l - 1; i >= 0; i--)
ans += c[i] + '0';
return ans;
}
};