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. UML组件图(转载)

    概述: 组件图是不同的性质和行为.组件图用于模拟物理方面的系统. 现在的问题是什么,这些物理方面?物理方面的元素,如可执行文件,库,文件,证件等它位于在一个节点. 因此,组件图用于可视化的组织和系统组 ...

  2. 使用Ext.Net时,配置文件的最简单写法

    使用Ext.Net时,配置文件的最简单写法 <?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配 ...

  3. 【JQuery NoviceToNinja系列】目录

    [JQuery NoviceToNinja系列]目录 [JQuery NoviceToNinja系列]01 开篇 Html页面设计和布局

  4. Git常用命令大全

    查看.添加.提交.删除.找回,重置修改文件 git help <command> # 显示command的help git show # 显示某次提交的内容 git show $id gi ...

  5. NGUI 自定义 Drag Item Script

    最近要实现一个NGUI效果. 查看了一下,NGUI有个自带 UIDragDropItem.cs 的组件进过修改后即可以实现. 下面贴上UI布局,代码: mDragDropItem.cs using U ...

  6. Masonry自动布局

    介绍,入门: http://www.cocoachina.com/ios/20141219/10702.html 下载: http://code.cocoachina.com/detail/30114 ...

  7. opal 将ruby代码转化成javascript

    点这里 https://github.com/opal Opal    Opal is a ruby to javascript source-to-source compiler. It also ...

  8. Nginx状态监控

    通过配置nginx.conf文件来实现对Nginx状态信息的监控. 1.配置nginx.conf vim /usr/local/nginx/conf/nginx.conf 再server块配置项中添加 ...

  9. 在 eclipse 中设置每行的字数

    在Preferences中:Java Code Style Formatter

  10. MyEclipse — Maven+Spring+Struts+Hibernate 整合 [学习笔记-2]

    引入Spring 修改 pox.xml 文件 添加jar包引用 <!-- spring3 --> <dependency> <groupId>org.springf ...