• 43.Multiply Strings


    给定两个字符串,都有数字组成,求这两个字符串所表示的数字的乘积,返回字符串表示形式。两个字符串的长度 < 110. 除了数字0本身,没有前导0存在。

    Input: num1 = "123", num2 = "456"
    Output: "56088"

    思路:
    一、由于字符串表示的数很大,几十上百位,肯定不能将其转化为数字再乘积,运用小学数学思想,比如:12 * 34 ,先用 12 * 4 = 48 ,再用 12 * 3 = 36 ,但是因为3是十位上的,相加的时候要移位,所以,48中的8保留不变,用 4 + 36 = 40 ,最终得到408. 不断的重复上面的过程,最终得到答案。虽然能AC,但是时间复杂度很高。

    class Solution {
    public:
        string multiply(string num1, string num2) {
            if (num1[0] == '0' || num2[0] == '0') return "0";
            string res, product, carry;
            int n1 = num1.size(), n2 = num2.size();
            for (int i = n1 - 1; i >= 0; i--) {
                int p1 = num1[i] - '0', tmp = 0, flag = 0;//进位的值 flag
                for (int j = n2 - 1; j >= 0; j--) {
                    tmp = p1 * (num2[j] - '0') + flag;
                    product = to_string(tmp % 10) + product;
                    flag = tmp / 10;
                }
                if (flag > 0) product = to_string(flag) + product;
                //获得一个字符串的一位值对另一个字符串的所有数字乘积,保存为字符串
                int res_len = res.size(), c = n1 - 1 - i;//移位个数 c
                carry = res;
                if (res_len > 0) {
                    carry = res.substr(0, res_len - c); // 移位过后,需要相加的字符串
                    res = res.substr(res_len - c, c); //移位留下的字符串,保留不变
                }
                res = twoStringSum(carry, product) + res; //两字符串相加得到的和,再接上移位留下的
                product = "";
            }
            return res;
        }
    
        string twoStringSum(string s1, string s2) { //两字符串相加
            string res;
            int n1 = s1.size(), n2 = s2.size(), flag = 0;
            if (n1 == 0 || n2 == 0) return n1 == 0 ? s2 : s1;
            while (n1 || n2) {
                int x1 = n1 > 0 ? s1[n1-1] - '0' : 0;
                int x2 = n2 > 0 ? s2[n2-1] - '0' : 0;
                int sum = x1 + x2 + flag;
                res = to_string(sum % 10) + res;
                flag = sum / 10;
                n1 = n1 > 0 ? n1 - 1 : 0;
                n2 = n2 > 0 ? n2 - 1 : 0;
            }
            if (flag > 0) res = to_string(flag) + res;
            return res;
        }
    };

    二、利用容器,空间换时间,参见Grandyang

    class Solution {
    public:
        string multiply(string num1, string num2) {
            string res = "";
            int m = num1.size(), n = num2.size();
            vector<int> vals(m + n);
            for (int i = m - 1; i >= 0; --i) {
                for (int j = n - 1; j >= 0; --j) {
                    int mul = (num1[i] - '0') * (num2[j] - '0');
                    int p1 = i + j, p2 = i + j + 1, sum = mul + vals[p2];
                    vals[p1] += sum / 10;
                    vals[p2] = sum % 10;
                }
            }
            for (int val : vals) {
                if (!res.empty() || val != 0) res.push_back(val + '0');
            }
            return res.empty() ? "0" : res;
        }
    };
  • 相关阅读:
    前端总结--性能优化
    Vue面试中,经常会被问到的面试题/Vue知识点整理
    面试怎么样?才会容易进入到心仪公司了
    Vuex,从入门到入门
    当面试官问你“有什么缺点”时,应如何体面的回答?
    Linux下文件搜索、查找、查看命令
    线程池运行机制
    win10右键很慢
    Linux 安装 Tomcat7
    Tomcat / Nginx 跨域
  • 原文地址:https://www.cnblogs.com/luo-c/p/12969290.html
Copyright © 2020-2023  润新知