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 ...
随机推荐
- JDBC数据库连接池原理
JDBC是java数据库连接的简称.它是一种用于实行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成.其相关的API都在java.sql.*包下 ...
- linux命令集——<一>目录处理命令
1.ls,命令,显示当前目录下文件 命令 所在路径 功能描述 执行权限 选项 说明 ls /bin/ls 显示目录文件 所有用户可用 -a 显示所有文件,包括隐藏文件 -l 显示详细信 ...
- c++ 遍历ini
inline void CDLG_SET1::EnumIniFile(LPCTSTR pFilePath, CString strKey) { TCHAR strAppNameTemp[];//所有A ...
- PE文件结构详解
(注:最左边是文件头的偏移量.) IMAGE_DOS_HEADER STRUCT { +0h WORD e_magic // Magic DOS signature MZ(4Dh 5Ah) DOS可执 ...
- Web流程
Web阻塞加载,异步加载. 延迟执行,立即执行. 加载并执行,不要调用代码. 加载并执行时会调用代码,但是加载并执行时不要调用代码,否则会改变逻辑. 上面是Web流程,JS只是web的一部分.如果关注 ...
- hadoop-ha QJM架构应用故障总结
部署hadoop-ha QJM架构过程我就不说了,参考 我的博客:hadoop-ha QJM架构部署故障一: namenode 报错日志如下: WARN org.apache.hadoop.hd ...
- python开发中常用的框架
以下是15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python Web应用开发框架 Django 应该是最出名的 ...
- 用 VIPER 构建 iOS 应用架构(2)
[编者按]本篇文章由 Jeff Gilbert 和 Conrad Stoll 共同编写,通过构建一个基础示例应用,深入了解 VIPER,并从视图.交互器等多个部件理清 VIPER 的整体布局及思路.通 ...
- HDU 1316 How Many Fibs?(java,简单题,大数)
题目 /** * compareTo:根据该数值是小于.等于.或大于 val 返回 -1.0 或 1: public int compareTo(BigInteger val) 将此 BigInteg ...
- Add and Search Word - Data structure design
https://leetcode.com/problems/add-and-search-word-data-structure-design/ Design a data structure tha ...