leetcode:Multiply Strings
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的更多相关文章
- leetcode:Multiply Strings(字符串的乘法)【面试算法题】
题目: Given two numbers represented as strings, return multiplication of the numbers as a string. Note ...
- LeetCode 043 Multiply Strings
题目要求:Multiply Strings Given two numbers represented as strings, return multiplication of the numbers ...
- [LeetCode] 43. Multiply Strings ☆☆☆(字符串相乘)
转载:43. Multiply Strings 题目描述 就是两个数相乘,输出结果,只不过数字很大很大,都是用 String 存储的.也就是传说中的大数相乘. 解法一 我们就模仿我们在纸上做乘法的过程 ...
- 【leetcode】Multiply Strings
Multiply Strings Given two numbers represented as strings, return multiplication of the numbers as a ...
- LeetCode OJ:Multiply Strings (字符串乘法)
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- [LeetCode] 43. Multiply Strings 字符串相乘
Given two non-negative integers num1 and num2represented as strings, return the product of num1 and ...
- LeetCode(43. Multiply Strings)
题目: Given two numbers represented as strings, return multiplication of the numbers as a string. Note ...
- Java for LeetCode 043 Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- 【leetcode】Multiply Strings(middle)
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
随机推荐
- 剑指offer--面试题23
//该题原本想用递归实现,但却用循环实现了... //关键用了个队列 #include <queue> void Print(BinaryTreeNode* pRoot, std::que ...
- Poj 1255 覆盖的面积 2014-07-28 12:29 116人阅读 评论(0) 收藏
覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- WebService流行框架之Axis和CXF
转自:http://www.cnblogs.com/snake-hand/archive/2013/06/09/3129915.html 前言 上节课我们对WebService进行了简单的介绍,对于其 ...
- 对话机器学习大神Yoshua Bengio(上)
Yoshua Bengio教授(个人主页)是机器学习大神之一,尤其是在深度学习这个领域.他连同Geoff Hinton老先生以及 Yann LeCun(燕乐存)教授,缔造了2006年开始的深度学习复兴 ...
- Shell日期时间和时间戳的转换
Gitlab的备份文件是以时间戳显示的,类似:1438624820_gitlab_backup.tar 为了更易于阅读,想把文件名转换成日期格式:2015-08-04_gitlab_backup.ta ...
- ASP.NET MVC中几个运用技巧
1. Razor Helpers 的运用:例如,定义好 ViewBag.Message = "Welcome to ASP.NET MVC!";我要在界面上显示"Welc ...
- Codeforces 475D CGCDSSQ(分治)
题意:给你一个序列a[i],对于每个询问xi,求出有多少个(l,r)对使得gcd(al,al+1...ar)=xi. 表面上是询问,其实只要处理出每个可能的gcd有多少个就好了,当左端点固定的时候,随 ...
- iOS第三方语音-讯飞语音
官方网站:http://www.xfyun.cn/ 注册还要绑定微信,坑啊,识别率感觉没得微信语音好,但是微信语音审核一直不过,研究下这个 1.下载sdk,主要就下面几个文件,我主要用的是语音识别
- 定时每天执行前一天的数据导入oracle
#!/bin/bash export LANG="en_US.UTF-8" #设定时间变量,为前一天时间 log_date=`date +%Y-%m-%d -d "-1 ...
- Session、Cookie及cache的区别
Session 是单用户的会话状态.当用户访问网站时,产生一个 sessionid.并存在于 cookies中.每次向服务器请求时,发送这个 cookies,再从服务器中检索是否有这个 session ...