[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.


思路:非常tricky的一道题。

        主要的思路是模拟一个手算乘法的过程,那么可以用一个二维矩阵去代替中间的步骤(即乘数的每一位与被乘数相乘所得的积)。第二步是错位相加,如果按照从上向下,从右向左来标记矩阵的index,可以发现相加的元素满足一个条件:行index和列index的和始终相等。于是想到,可以压缩到一个一维矩阵。在这个过程中,并不去处理进位的问题,每一个element可能是多位数。reverse的作用在于使得两个string的末尾对齐,不然对于index的操作会非常繁琐。

        接下来就是如何从这个和的数组中取出所有的位。由于和只能从后往前取,最后的结果需要从前往后生成,当然从后向前生成,利用str.insert(0, digit)不断的插入,但是这样会造成内存的反复读写。于是想到用一个stack去读,之后还需要把carry生成的位全部读进去。

        最后需要注意的是开头可能会有0,需要忽略掉,但是如果全是0,需要保留最后一个。


class Solution {
public:
    string multiply(string num1, string num2) {
        reverse(num1.begin(), num1.end());
        reverse(num2.begin(), num2.end());
        int len1 = (int)num1.size();
        int len2 = (int)num2.size();
        vector<int> temp(len1 + len2, 0);
        for (int i = 0; i < len2; ++i) {
            for (int j = 0; j < len1; ++j) {
                temp[i+j] += (num2[i] - '0') * (num1[j] - '0');
            }
        }
        int carry = 0;
        stack<int> s_result;
        // get all the digits from the temp array
        for (int i = 0; i < (int)temp.size(); ++i) {
            s_result.push((temp[i] + carry) % 10);
            carry = (temp[i] + carry) / 10;
        }
        // get all the digits generated by the carry
        while (carry > 0) {
            s_result.push(carry % 10);
            carry /= 10;
        }
        // discard all the '0's in the front, but should leave one
        while (s_result.top() == 0 && s_result.size() > 1) s_result.pop();
        string result = "";
        while (!s_result.empty()) {
            result.push_back(s_result.top() + '0');
            s_result.pop();
        }
        return result;
    }
};


总结:复杂度为O(nlogn). 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值