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);
    }
};

  

 

时间: 2024-11-09 07:30:42

leetcode:Multiply Strings的相关文章

LeetCode 043 Multiply Strings

题目要求: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. 分析: 参考网址:http://blog.csdn.net/pickless/article/details/9235907 利用竖式的思想,

每日算法之三十四:Multiply Strings

大数相乘,分别都是用字符串表示的两个大数,求相乘之后的结果表示. 首先我们应该考虑一下测试用例会有哪些,先准备测试用例对防御性编程会有比较大的帮助,能够考虑一些极端情况.有以下几种用例: 1)"0","0" 2)"0","879127346783" 其中一个是零 3)"as234","123343"  存在非法字符 4)"000000000000001234",&qu

LeetCode:Isomorphic Strings

1.题目名称 Isomorphic Strings(同构的字符串) 2.题目地址 https://leetcode.com/problems/isomorphic-strings/ 3.题目内容 英文: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurre

【LeetCode】Multiply Strings

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. 我借鉴了JackBauer的一些思想,将乘积逆序存放在int数组result中. 记num1当前为第ind1位(个位为0),num2当前为ind2位,则

LeetCode OJ: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. 给出两个字符串,返回对应数字想乘后的字符串,由于这个字符串可能很大,所以不能采用一般的乘法,这里用的方法是模拟手工的乘法运算,算法 本身很简单,就是当时写的时候有些很小的细节搞错了,找了

LeetCode (19) 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. 对两组非负数字进行相乘,使用数组表示数字,且题目中说明数组很大,因此,因此不能直接将数组转换成数字相乘.这道题目是要求自己构造乘法的思路,需要注意的地方主要为进位的处理. 解题

Java [Leetcode 43]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. 解题思路: 设置数组记录单个位置相乘的结果,最后负责相加进位. 代码如下: public class Solution { public String multiply(St

【leetcode】Multiply Strings(middle)

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. 思路:直观思路,就是模拟乘法过程.注意进位.我写的比较繁琐. string multiply(string num1, string num2) { vector<int> v1, v

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. 这道题的意思是字符串表示的数字相乘. 没啥好说的直接付代码. public String multiply(String num1, String num2) { BigInteger