zoukankan      html  css  js  c++  java
  • 【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/

  • 相关阅读:
    [leetcode]Combination SumII
    NSum小结
    image 与 canvas 的相互转化
    $_SERVER 相关变量
    最近做的项目,总结一下。
    开始在博客园,写博客,先写点东西。
    Codeforces Round #584 C. Paint the Digits
    Codeforces Round #584 B. Koala and Lights
    Codeforces Round #584 A. Paint the Numbers
    HDU-2296-Ring(AC自动机, DP)
  • 原文地址:https://www.cnblogs.com/flix/p/12687561.html
Copyright © 2011-2022 走看看