题解 | #大数乘法#

大数乘法

http://www.nowcoder.com/practice/c4c488d4d40d4c4e9824c3650f7d5571

题解一:普通竖式法
题解思路: 模拟拆分乘法竖式,遍历t,每次相乘之和末位补n-1-i个零之后,与之前的值相加
图示:
图片说明
复杂度分析:
时间复杂度:O(MN+N^2): M为s的长度,N为t的长度,中间存储字符串最长为(M+N),需要乘以N次,所以字符串相加次数也为N。所以时间复杂度为O((M+N)N)
空间复杂度:O(M+N):需要一个存储中间值的字符串,该字符串最长为(M+N);
实现如下:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param s string字符串 第一个整数
     * @param t string字符串 第二个整数
     * @return string字符串
     */
    string add_string(string &s1,string &s2){
        if(s1=="0") return s2;
        int len1 = s1.length()-1,len2 = s2.length()-1;
        int jinwei = 0;  // 有没有进位
        string ans;
        while(len1>=0 || len2>=0 || jinwei>0)
        {
            int val1 = len1 >= 0 ? s1.at(len1) - '0' : 0;  // 提取s1各个位的值,将其转为int
            int val2 = len2 >= 0 ? s2.at(len2) - '0' : 0;  //提取s2各个位的值,将其转为int
            int res = val1 + val2 +jinwei;                 
            jinwei = res / 10;
            ans += to_string(res % 10);   // ans 加上相加之后的个位
            len1 --;
            len2 --;
        }
        reverse(ans.begin(),  ans.end()); // 同样,ans保存的是相加之后的逆序,所以需要翻转
        return ans;
    }
    string solve(string s, string t) {
        // write code here
        if(s == "0" || t == "0") return "0"; //判断是否是乘0
        int m = s.size();  //s的长度
        int n = t.size();  // t的长度
        string ans = "0"; //存储最后的答案
        for(int i = n-1;i>=0; i--)
        {
            string cur; // 存储本次乘法所产生的中间值
            int jinwei = 0; // 保存进位的值
            for(int j = n-1;j>i;j--) // 补n-1-i个0
                cur.push_back('0');
            int val = t.at(i) - '0';  //当前要乘以s的值,转为int型
            for(int j = m-1;j>=0;j--)  //循环取数相乘
            {
                int x = s.at(j) - '0';
                int pro = x * val + jinwei; // 相乘加上之前的进位
                jinwei = pro/10;            //需要向下一轮进位的数
                cur += to_string(pro % 10); // 加入当前乘完之后的个位上的值
            }
            if(jinwei) cur += to_string(jinwei);  //如果所有位乘完,进位值不为0,再将进位值加到末尾
            reverse(cur.begin(), cur.end()); //cur保存的是乘完之后值的逆序,需要翻转
            ans = add_string(ans, cur); // 加上中间值
          }
        return ans;
     }
};

题解二:多项式乘法
题解思路: 将每个数转换为多项式表示,这样就利用多项式乘法对其求积。
分析:
1.一个任意n位梳子可以用n-1次多项式表示:
图片说明

2.两个多项式乘法,用A(x)和B(x)表示两个数:
图片说明
可以看出得到的多项式:a与b的下标之和要等于幂次; 即 c(x):
图片说明

其中m与n分别是两个数的长度。

复杂度分析:
时间复杂度:O(MN);多项式每一项都要与另一个数的多项式每一项相乘,如上图所示
空间复杂度:O(M+N);最差两个多项式的x次方都不相同,需要M+N的空间存储对应次方的系数
实现如下:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param s string字符串 第一个整数
     * @param t string字符串 第二个整数
     * @return string字符串
     */
    string solve(string s, string t) {
        if(s == "0" || t == "0") return "0"; // 乘以0直接返回字符串“0”
        int m = s.length(), n = t.length();
        vector<int> ans = vector<int>(m+n);  //用于保存相应幂次的权值
        for(int i = 0;i<m;i++)
        {
            int x = s[i]-'0';
            for(int j = 0;j<n;j++)
            {
                int y = t[j] - '0';
                ans[m+n-2-i-j] += x*y;   // 将权重加到相应幂次位上
            }
        }
        // 从低位向高位进位
        for(int i = 0;i<=m+n-2;i++)
        {
            ans[i+1] += ans[i] /10; // 向高位进位
            ans[i]  = ans[i] %10;
        }
        //最后是否有进位到最高位
        int index = (ans[m+n-1] == 0 ? m+n-2 : m+n-1);

        //从最高位组成字符串
        string res;
        while(index>=0){
            int tmp = ans[index--];
            res += to_string(tmp);
        }
        return res;
    }
};
牛客网编程题题解 文章被收录于专栏

本专栏记录在牛客网上AC的每一题,写下题解。 未来2年完成2000编程题的题解。 2021.12.29更新,最进准备毕设,断更了,会尽快做完毕设,继续做这一件事情

全部评论
第二个,好像看懂了, 好像没有懂
1 回复 分享
发布于 2022-02-20 01:10
您说的是第几个解法,空间复杂度才是O(M+N)
点赞 回复 分享
发布于 2021-08-03 09:11

相关推荐

头像
昨天 20:13
中南大学 Java
序言大家好呀。我是希晨er,一个初入职场的程序猿小登最近上班摸鱼刷到了一篇文章:10年深漂,放弃高薪,回长沙一年有感,还有聊聊30岁大龄程序员过往的心路历程,突然就有点感慨。我如今也做出了和大明哥一样的抉择,只是更早。此外我22年的人生,好像从来没好好记录过。正好现在工作不太忙,就想把这些经历写下来,也希望能得到社区里各位前辈的指点个人背景我是03年出生的西安娃,父母都是普通打工人。刚从中南大学软件工程专业毕业半年,现在在老家的央企过着躺平摆烂的日子成长轨迹从农村到城市的童年我家并不是西安的,只是爸妈在西安上班,从小学之后就把我接到了西安。后来老家房子拆了,爷爷奶奶也搬了过来。农村的生活,我觉...
Yki_:看哭了,恋爱那一段你女朋友说你不够关心她,可你毕竟也愿意遇到矛盾写几千字来和她慢慢分析;说不愿意给她花钱,我感觉可能只是消费观不一样;如果她想留在长沙,也应该提前跟你说开。不过她也许会心疼你放弃大厂offer转向数字马力?我也因为同样的原因有过一段幸福而充满遗憾的感情,不过跟爱情相比确实前途更重要一点。至于offer的选择,换我我也会这么选。把这些旧事记录下来以后,接下来就好好向前看吧,加油兄弟
🍊晨光随笔
点赞 评论 收藏
分享
评论
4
6
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务