【LeetCode-字符串】字符串相乘

题目描述

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
示例:

输入: num1 = "2", num2 = "3"
输出: "6"

输入: num1 = "123", num2 = "456"
输出: "56088"

题目链接: https://leetcode-cn.com/problems/multiply-strings/
做这题之前可以先做一下字符串相加

思路1

模拟人做乘法,两个数相乘,首先将第一个数和第二个数的最后一位相乘,然后将第一个数和第二个数的倒数第二位相乘并左移一位和之前的结果相加,这里就要用到大整数的加法。

代码如下:

class Solution {
public:
    string multiply(string num1, string num2) {
        if(num1=="0" || num2=="0") return "0";
        if(num1=="1") return num2;
        if(num2=="1") return num1;
        
        string ans = "";
        for(int i=num2.size()-1, j=0; i>=0; i--){
            string mulRes = mul(num1, num2[i]);
            for(int k=0; k<j; k++){ // 左移相当于后面补零
                mulRes += "0";
            }
            ans = add(ans, mulRes);
            j++;
        }
        return ans;
    }

    /*字符串str和字符c相乘,返回相乘后的结果*/
    string mul(string str, char c){
        int carry = 0;
        string res = "";
        for(int i=str.length()-1; i>=0; i--){
            int t = (str[i]-'0')*(c-'0')+carry;
            res = to_string(t%10)+res;
            carry = t/10;
        }
        if(carry!=0) res = to_string(carry)+res;
        return res;
    }

    /*字符串s1和字符串s2相加,返回相加后的结果*/
    string add(string s1, string s2){
        if(s1=="" || s1=="0") return s2;
        if(s2=="" || s2=="0") return s1;
        
        int l1 = s1.length()-1;
        int l2 = s2.length()-1;
        int carry = 0;
        string ans = "";
        while(l1>=0 || l2>=0){
            int x = (l1>=0)? s1[l1]:'0';    // 注意是'0',不是0
            int y = (l2>=0)? s2[l2]:'0';    // 注意是'0',不是0
            int s = (x-'0')+(y-'0')+carry;
            ans = to_string(s%10)+ans;
            carry = s/10;
            if(l1>=0) l1--;
            if(l2>=0) l2--;
        }
        if(carry!=0) ans = "1"+ans;
        return ans;
    }
};
  • 时间复杂度:O(mn)
    m,n分别是num1和num2的长度。
  • 空间复杂度:O(m+n)
    m,n分别是num1和num2的长度。

思路2

使用性质:

  • 长为n的数和长为m的数相乘的结果最大长度为m+n;
  • 结果存在数组res中,num1[i]*num2[j]的结果为两位数tmp(0x或者xy),其中第一位位于res[i+j], 第二位位于res[i+j+1]。

代码如下:

class Solution {
public:
    string multiply(string num1, string num2) {
        if(num1=="0" || num2=="0") return "0";
        if(num1=="1") return num2;
        if(num2=="1") return num1;
        
        /// int* res = new int[num1.length()+num2.length()]; // 用new会错,不清楚原因
        int res[num1.length()+num2.length()];
        memset(res, 0, sizeof(res));
        for(int i=num1.length()-1; i>=0; i--){
            int n1 = num1[i]-'0';
            for(int j=num2.length()-1; j>=0; j--){
                int n2 = num2[j]-'0';
                int s = res[i+j+1]+n1*n2;
                res[i+j+1] = s%10;  // 低位
                res[i+j] += s/10;   // 高位
            }
        }

        string ans = "";
        for(int i=0; i<num1.length()+num2.length(); i++){
            if(i==0 && res[i]==0) continue;
            ans += to_string(res[i]);
        }
        return ans;
    }
};
  • 时间复杂度:O(mn)
    m,n分别是num1和num2的长度。
  • 空间复杂度:O(m+n)
    m,n分别是num1和num2的长度。

相关题目

1、字符串相加: https://leetcode-cn.com/problems/add-strings/,题解

参考

思路 2 参考了:https://leetcode-cn.com/problems/multiply-strings/solution/you-hua-ban-shu-shi-da-bai-994-by-breezean/

posted @ 2020-04-12 21:47  Flix  阅读(3055)  评论(0编辑  收藏  举报