Given two numbers represented as strings, return multiplication of the numbers as a string.

Note: The numbers can be arbitrarily large and are non-negative.

第一眼看到这个题目,潜意识里觉得直接将字符串转换为数字相乘,然后将结果再转换为字符串,难道这题考的是字符串与数值之间的转换?

细看,发现数字可能非常大,那么问题来了:这个数据类型怎么定义呢?显然这种思路完全是错的了。

那么怎么解决这个问题呢?仔细一想问题可能在于如何理解这个乘法过程(题目中multiply可是关键字)了。由于经验尚浅,花了一些时间去琢磨,最后参照一些资料做出了如下分析:(算法题还是有很多值得用心思考的地方的,要学会抓住解决问题的痛点,和把握细节)

1、要模拟竖式乘法的计算过程(透过问题看本质)

2、这个过程有乘法思维,还有加法思维在里面(因为涉及到进位)

3、要把乘法和加法操作过程分清楚,每次一个新位与被乘数相乘之前,都要加上进位再处理。(注意细节)

4、为了顺应习惯,把两个数字reverse过来再操作,最后还原顺序。

代码如下:

class Solution {
public:
string multiply(string num1, string num2) {
int m = num1.size(), n = num2.size();//字符串元素个数
if (num1 == "0" || num2 == "0") return "0";
vector<int> res(m+n, 0);
reverse(begin(num1),end(num1));//字符串反转
reverse(begin(num2),end(num2));
for (int i = 0; i < n; ++i)
for (int idx = i, j = 0; j < m; ++j)
res[idx++] += (num2[i]-'0')*(num1[j]-'0');// 字符转化为数字然后相乘(ascll码) int carry = 0;
for (int i = 0; i < m+n; ++i) {
int tmp = res[i];
res[i] = (tmp+carry)%10;
carry = (tmp+carry)/10;//进位
} string str(m+n,'0');
for (int k = 0, i = res.size()-1; i >= 0; --i) str[k++] = res[i]+'0';//还原顺序
auto idx = str.find_first_not_of('0');//将str字符串中第一个不匹配字符‘0’的索引值赋给idx
return str.substr(idx);//从起始字符序号idx开始取得str中的子字符串(消除了前面的0)
}
};

 其他解法:

1、
class Solution {
public:
string multiply(string num1, string num2) {
string sum(num1.size() + num2.size(), '0'); for (int i = num1.size() - 1; 0 <= i; --i) {
int carry = 0;
for (int j = num2.size() - 1; 0 <= j; --j) {
int tmp = (sum[i + j + 1] - '0') + (num1[i] - '0') * (num2[j] - '0') + carry;
sum[i + j + 1] = tmp % 10 + '0';
carry = tmp / 10;
}
sum[i] += carry;
} size_t startpos = sum.find_first_not_of("0");
if (string::npos != startpos) {
return sum.substr(startpos);
}
return "0";
}
};

 

This is an example of the pretty straightforward but very efficient C++ solution with 8ms runtime on OJ. It seems most of people here implemented solutions with base10 arithmetic, however that is suboptimal. We should use a different base.

This was a hint. Now stop, think, and consider coding your own solution before reading the spoiler below.

The idea used in the algorithm below is to interpret number as number written in base 1 000 000 000 as we decode it from string. Why 10^9? It is max 10^n number which fits into 32-bit integer. Then we apply the same logic as we used to hate in school math classes, but on digits which range from 0 to 10^9-1.

You can compare the multiplication logic in other posted base10 and this base1e9 solutions and you'll see that they follow exactly same pattern.

Note, that we have to use 64-bit multiplication here and the carry has to be a 32-bit value as well

class Solution {
public:
void toBase1e9(const string& str, vector<uint32_t>& out)
{
int i = str.size() - 1;
uint32_t v = 0;
uint32_t f = 1;
do
{
int n = str[i] - '0';
v = v + n * f;
if (f == 100000000) {
out.push_back(v);
v = 0;
f = 1;
}
else {
f *= 10;
}
i--;
} while (i >= 0);
if (f != 1) {
out.push_back(v);
}
} string fromBase1e9(const vector<uint32_t>& num)
{
stringstream s;
for (int i = num.size() - 1; i >= 0; i--) {
s << num[i];
s << setw(9) << setfill('0');
}
return s.str();
} string multiply(string num1, string num2)
{
if (num1.size() == 0 || num2.size() == 0)
return "0";
vector<uint32_t> d1;
toBase1e9(num1, d1);
vector<uint32_t> d2;
toBase1e9(num2, d2);
vector<uint32_t> result;
for (int j = 0; j < d2.size(); j++) {
uint32_t n2 = d2[j];
int p = j;
uint32_t c = 0;
for (int i = 0; i < d1.size(); i++) {
if (result.size() <= p)
result.push_back(0);
uint32_t n1 = d1[i];
uint64_t r = n2;
r *= n1;
r += result[p];
r += c;
result[p] = r % 1000000000;
c = r / 1000000000;
p++;
}
if (c) {
if (result.size() <= p)
result.push_back(0);
result[p] = c;
}
} return fromBase1e9(result);
}
};

  

 

leetcode:Multiply Strings的更多相关文章

  1. leetcode:Multiply Strings(字符串的乘法)【面试算法题】

    题目: Given two numbers represented as strings, return multiplication of the numbers as a string. Note ...

  2. LeetCode 043 Multiply Strings

    题目要求:Multiply Strings Given two numbers represented as strings, return multiplication of the numbers ...

  3. [LeetCode] 43. Multiply Strings ☆☆☆(字符串相乘)

    转载:43. Multiply Strings 题目描述 就是两个数相乘,输出结果,只不过数字很大很大,都是用 String 存储的.也就是传说中的大数相乘. 解法一 我们就模仿我们在纸上做乘法的过程 ...

  4. 【leetcode】Multiply Strings

    Multiply Strings Given two numbers represented as strings, return multiplication of the numbers as a ...

  5. LeetCode OJ:Multiply Strings (字符串乘法)

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  6. [LeetCode] 43. Multiply Strings 字符串相乘

    Given two non-negative integers num1 and num2represented as strings, return the product of num1 and  ...

  7. LeetCode(43. Multiply Strings)

    题目: Given two numbers represented as strings, return multiplication of the numbers as a string. Note ...

  8. Java for LeetCode 043 Multiply Strings

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  9. 【leetcode】Multiply Strings(middle)

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

随机推荐

  1. Basic knowledge of javaScript (keep for myself)

    1. 函数表达式 JavaScript 函数可以通过一个表达式定义.eg. var x = function (a, b) {return a * b}; so: var x = function ( ...

  2. HTTP1.1缓存策略

    以下是一幅虽然信息包含量有限.但足够以最简洁的方式说明了“什么是HTTP1.1缓存策略”的图  缓存和缓存策略 web缓存(web cache)或代理缓存(proxy cache)是一种特殊的HTTP ...

  3. share干什么的

    share到底干什么的 //--------------------打开GameServer,share中加载------------------------- .加载nBodyID //玩家的nBo ...

  4. jdbc读取数据库表

    把结果集封装为List // 通过结果集元数据封装List结果集 public static List<Map<String, Object>> read(String sql ...

  5. MyEclipse提示键配置、提示快捷键、提示背景色、关键字颜色、代码显示、编...

    1.提示键配置 一般默认情况下,Eclipse ,MyEclipse 的代码提示功能是比Microsoft Visual Studio的差很多的,主要是Eclipse ,MyEclipse本身有很多选 ...

  6. [转载]为什么我希望用C而不是C++来实现ZeroMQ

    来源: http://blog.jobbole.com/19647/ 开始前我要先做个澄清:这篇文章同Linus Torvalds这种死忠C程序员吐槽C++的观点是不同的.在我的整个职业生涯里我都在使 ...

  7. js函数延迟执行

    function delay(value){ //全局变量保存当前值 window._myTempDalayValue = value; setTimeout(function(){ //延时之后与全 ...

  8. Sqli-labs less 15

    Less-15 本关没有错误提示,那么我们只能靠猜测进行注入.这里我直接从源代码中看到了sql语句 @$sql="SELECT username, password FROM users W ...

  9. 导出含有图片的项目成jar文件后运行,图片不显示

    在编写完Java程序后,打包成Jar时发布,会发现找不到Jar文件中的图片和文本文件,其原因是程序中载入图片或文本文件时,使用了以当前工作路径为基准的方式来指定文件和路径.这与用户运行Jar包时的当前 ...

  10. HYSBZ2038 小Z的袜子(莫队算法)

    今天学了一下传说中的解决离线询问不修改的一种算法.题目的意思非常简单,就是询问在一个[L,R]区间里的取两个物品,然后这两个物品颜色相同的概率.其实就是对于每种颜色i,这个区间里对应的个数cnt[i] ...