LeetCode 43. Multiply Strings

1. 题目分析

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.
Converting the input string to integer is NOT allowed.
You should NOT use internal library such as BigInteger.

2. 解题思路

首先, 我们知道 m 位数 乘以 n 位数 所得到的结果最大一定不超过 m + n 位。那么, 我们可以定义一个长度为 m + n 的数组, 按照乘法的法则, 依次将对应项的乘积放入到相应的位置, 然后,遍历数组进行进位处理, 得到一个最终结果的字符串, 不过需要注意的是, 需要去除字符串中的前导零。

3. code

class Solution {
public:
    string multiply(string num1, string num2) {
        int len_1 = num1.size();
        int len_2 = num2.size();
        vector<int> arr(len_1 + len_2, 0);
        for (int i = 0; i != len_1; i++){
            for (int j = 0; j != len_2; j++){
                int n1 = num1[len_1 - 1 - i] - '0';
                int n2 = num2[len_2 - 1 - j] - '0';
                int sum = n1 * n2;
                arr[len_1 + len_2 - 1 - i - j] += sum;
            }
        }

        string res;
        int addition = 0;
        for (int i = len_1 + len_2 - 1; i >= 0; i--){
            int sum = arr[i] + addition;
            res = to_string(sum % 10) + res;
            addition = sum / 10;
        }

        int pos = res.find_first_not_of('0');
        if (pos != -1)
            return res.substr(pos);
        return "0";
    }
};

4. 大神解法

4.1 demo1

通过分析两位数相乘所影响的相应的数据位, 直接循环求解

/*
Remember how we do multiplication?

Start from right to left, perform multiplication on every pair of digits, and add them together. Let's draw the process! From the following draft, we can immediately conclude:

 `num1[i] * num2[j]` will be placed at indices `[i + j`, `i + j + 1]` 
Multiplication

Here is my solution. Hope it helps!
*/
public String multiply(String num1, String num2) {
    int m = num1.length(), n = num2.length();
    int[] pos = new int[m + n];

    for(int i = m - 1; i >= 0; i--) {
        for(int j = n - 1; j >= 0; j--) {
            int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0'); 
            int p1 = i + j, p2 = i + j + 1;
            int sum = mul + pos[p2];

            pos[p1] += sum / 10;
            pos[p2] = (sum) % 10;
        }
    }  

    StringBuilder sb = new StringBuilder();
    for(int p : pos) if(!(sb.length() == 0 && p == 0)) sb.append(p);
    return sb.length() == 0 ? "0" : sb.toString();
}

4.2 demo2

与demo1 类似的思想

/*
This is the standard manual multiplication algorithm. We use two nested for loops, working backward from the end of each input number. We pre-allocate our result and accumulate our partial result in there. One special case to note is when our carry requires us to write to our sum string outside of our for loop.

At the end, we trim any leading zeros, or return 0 if we computed nothing but zeros.
*/
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";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值