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. GPU crash unmap page access

    这类gpu crash是 texture 没有gpu address 调试方法 去看texture,  texture state 里面allocateMemoryBlock...这里面有gpuadd ...

  2. [工作积累] 32bit to 64bit: array index underflow

    先贴一段C++标准(ISO/IEC 14882:2003): 5.2.1 Subscripting: 1 A postfix expression followed by an expression ...

  3. Spring MVC学习问题记录

    自2015年3月11日开始进行记录 day01 2015.03.11 问题1:Line 1 in XML document from URL is invalid; 今天出现了Content is n ...

  4. Xamarin 中开发Android实现全屏或者不显示标题栏的方法-宋兴柱

    using System; using Android.App; using Android.Content; using Android.Runtime; using Android.Views; ...

  5. Codeforces Round #216 (Div. 2)解题报告

    又范低级错误! 只做了两题!一道还被HACK了,囧! A:看了很久!应该是到语文题: 代码:#include<iostream> #include<];    ,m2=;    ;i ...

  6. ASP.NET制作一个简单的等待窗口

    前一阵做一个项目,在处理报表的时候时间偏长,客户提出要做出一个等待窗口提示用户等待(页面太久没反映,用户还以为死了呢).在分析这一需求之后,觉得如果要实现像winform应用中的processbar太 ...

  7. jquery ajax清除缓存的方法

    function cityListChange(cityCode){ //{lon=121.491121, name=上海, province=上海市, telPrefix=021, province ...

  8. Sqli-labs less 52

    Less-52 和less50是一样的,只是这里的mysql错误不会在前台显示,但是对于stacked injection是一样的利用方式 http://127.0.0.1/sqli-labs/Les ...

  9. cf div2 236 D

    D. Upgrading Array time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  10. SGU 102

    For given integer N (1<=N<=104) find amount of positive numbers not greater than N that coprim ...