leetcode第一刷_Multiply Strings

前面提到过很多次大整数的问题,这个是真正的大整数。

我用了一个很蠢得方法,先写一个大整数和一个个位数相乘的方法,返回的结果是一个string,然后写一个string相加的方法,每次循环,用其中一个数的每一位去乘另一个数,然后加到结果上。。

多么愚蠢的思路,居然还一遍过了。。一个更好的方法是先用两个int数组把两个string存一下,每位占数组中的一个数,然后再用一个int数组保存结果,每次也是用一个数的每一位去乘另一个数,结果直接加入到结果数组的对应位置,不考虑进位,最后再统一的计算进位。这种思路非常简单,应当用我一半的代码就能写完,而且不容易出错。一般也不会溢出,因为每次乘得到的数最大是81,要相加超过INT_MAX,string得非常长才行。

下面贴我自己的代码,供大家耻笑:

void reverse(string &s){
    int len = s.length();
    for(int i=0;i<len/2;i++){
        char t = s[i];
        s[i] = s[len-i-1];
        s[len-i-1] = t;
    }
}

string stringPlus(string a, string b){
    int len1 = a.length(), len2 = b.length();
    string res(max(len1, len2)+1, ‘0‘);
    int i = 0, j = 0, len = min(len1, len2), c=0;
    while(i<len){
        int t = (a[i]-‘0‘) + (b[i]-‘0‘) + c;
        res[i] = t%10 + ‘0‘;
        c = t/10;
        i++;
    }
    while(i<len1){
        if(c>0){
            int t = (a[i]-‘0‘) + c;
            res[i] = t%10+‘0‘;
            c = t/10;
        }else{
            res[i] = a[i];
        }
        i++;
    }
    while(i<len2){
        if(c>0){
            int t = (b[i]-‘0‘) + c;
            res[i] = t%10+‘0‘;
            c = t/10;
        }else{
            res[i] = b[i];
        }
        i++;
    }
    return res;
}

string numPlus(string &a, int low, int bit){
    int len = a.length();
    string res(len+bit+1, ‘0‘);
    int start = bit, i=0, c=0;
    while(i<len){
        int t = (a[i]-‘0‘)*low + c;
        res[start] = t%10+‘0‘;
        c = t/10;
        i++;
        start++;
    }
    if(c>0)
        res[start] = c+‘0‘;
    return res;
}

class Solution {
public:
    string multiply(string num1, string num2) {
        if(num1 == "")
            return num2;
        if(num2 == "")
            return num1;
        string res = "0";
        reverse(num1); reverse(num2);
        for(int i=0;i<num2.length();i++){
            res = stringPlus(res, numPlus(num1, num2[i]-‘0‘, i));
        }
        int len = res.length();
        while(len-1&&res[len-1] == ‘0‘)
        	len--;
        string mres(len, ‘0‘);
		for(int i=0;i<len;i++){
			mres[i] = res[len-i-1];
		}
        return mres;
    }
};

leetcode第一刷_Multiply Strings

时间: 2024-11-06 12:22:18

leetcode第一刷_Multiply Strings的相关文章

leetcode第一刷_Binary Tree Inorder Traversal

递归实现当然太简单,也用不着为了ac走这样的捷径吧..非递归实现还挺有意思的. 树的非递归遍历一定要借助栈,相当于把原来编译器做的事情显式的写出来.对于中序遍历,先要訪问最左下的节点,一定是进入循环后,不断的往左下走,走到不能走为止,这时候,能够从栈中弹出訪问的节点,相当于"左根右"过程的"根",然后应该怎么做呢?想一下中序遍历完根节点之后应该干嘛,对,是走到右子树中继续反复这个过程,可是有一点,假设这个节点不包括右子树怎么办?这样的情况下,下一个应该訪问的节点应该

leetcode第一刷_Sqrt(x)

这道题乍看下来非常简单,实际上要注意的问题非常多. 注意看给出来的函数的接口,返回的是int值,也就是计算结果是个近似值.怎样求呢?难道是从2开始往上算?直到某个值正好接近x?当然不行,肯定超时了.再仔细想一下,对了,有二分法,从最大的开始,每次计算一下平方,如果结果比x大,那么缩短上界,否则提高下界. 思想很正确,下面的问题是最大的那个值是多少?你会毫不犹豫的说出是x啊,x的平方根肯定比x小吧.好,那如果x是INT_MAX呢,你想用什么类型来存储这个平方的结果?而且这样每次减半,也得好一会儿才

leetcode第一刷_Subsets II

要求子集,有非常现成的方法.N个数,子集的个数是2^N,每个元素都有在集合中和不在集合中两种状态,这些状态用[0,pow(2,N)]中每个数来穷举,如果这个数中的第i位为1,说明当前集合中包含源数组中的第i个数. 至于有没有重复的元素,大部分有重复元素的问题,都可以借助一个vis集合,里面存放所有已经求得的集合或者其他形式的解,只有少数题目会超时,哪些问题具体的说. class Solution { public: vector<vector<int> > subsetsWithD

leetcode第一刷_Decode Ways

这道题还挺难的.递归的思路是好想,不过不出意料的超时了. dp嘛.想一下i-1的编码加上第i个编码会怎样,如果加上的这个编码不是0,那么这一位可以独立解码,那长为i的解码个数至少是长为i-1的解码个数.还有呢?如果i-1位是1,可以把i-1位和i位同时解码出来,还有呢?如果i-1位是2而i位是0-6中的数字,也可以同时解码这两位编码.满足这个条件的时候,当前长度的解码个数还要加上i-2时的解码个数. 完全可以用一个数组存放过去的结果,但是很明显,当前的结论只与前一个和前前一个结果有关系.只要用三

leetcode第一刷_Gray Code

说到格雷码,应该没人不知道,具体它有什么用,我还真不是很清楚,我室友应该是专家.生成的规律不是很明显,之前看到帖子讲的,这会儿找找不到了.. 思想是这样的,如果有n位,在第2^(n-1)个编码下面画一条水平线的话,你会发现除了第一位之外,其他位都是关于这条线对称的,如下,以三位格雷码举例: 000 001 011 010 --------------------- 110 111 101 100 很神奇吧,我以前是不知道这个规律的.从一开始的一位格雷码,0,1,开始,每次对称的在上一个前面添加上

leetcode第一刷_Permutation Sequence

这道题还挺好的,如果你的思路是每次生成一个全排列,然后累计到k次,那么停下来吧,肯定超时了亲.. 微软今年的笔试题里有一道类似的,我之前已经提到过了,是只有0和1的字符串,求第k个排列是什么样子的.这道题比那个要难一些,但是总体的思路是一样的.假设有n个数要组成排列,求第k个排列.像填表一样,从高位往地位,逐个填写.先考虑有n-1个数要组成排列,最多有(n-1)!种情况,当第n个数加入后,第n个数可以是从1增加到n的,没增加1,所包含的全排列数就会增加(n-1)!,因此,如果用k/(n-1)!,

leetcode第一刷_Spiral Matrix

我觉得这个题好无聊啊,好端端一个数组,干嘛要跟比巴卜一样转一圈输出呢.. 思想很简单,每次从左到右,再从上到下,在从右到左,再从下到上.问题是每次到什么时候该改变方向.我的做法是用一个变量保存当前在第几层,这个层是相对于从外向内有几圈来说的.注意想清楚边界的话这个题一点也不难.有个细节,我的循环退出条件是访问的数跟矩阵总个数之间的关系,如果有一次在判断进入循环是条件是满足的,但是在循环内部不满足了,我的策略是忽略这种情况,虽然这样会在结果集中多加一些重复的数据,但是以我的算法,一定是先访问没有访

leetcode第一刷_Scramble String

字符串的好题.题干解释的非常复杂,一下让人不知所措了. 这道题到底是什么意思呢?最终的结果是把一个字符串中字母的顺序打乱了,让你判断一个字符串能不能由另一个字符串打乱得到.那打乱这个过程是怎么做的呢,很简单,给你一个字符串,你必须先找一个点把它砍成两半,你可以通过交换这两半的顺序来打乱源字符串的顺序,也就是在两半中的字符与另一半中所有字符的相对顺序是统一的.对于每一半,都可以重复上面的过程. 那想一下,怎么知道打断的那个点在哪呢?穷举.怎么知道打断之后有没有做交换操作呢?两种情况递归,有一条走的

leetcode第一刷_Partition List

partition是快排的准备工作,被用在其他很多问题上,比如找满足某个条件的数之类的. 在数组中,可以一头一尾的指针依次置换,这样是不能保证源数组中的相对顺序的.链表中就不一样了,没办法拿到尾部的指针,只能从头部往后找,找到第一不满足partition条件的节点,即较大的数,然后再往后找较小数,把较小数的节点移到前面来,因此跟数组的做法还有个区别,链表的partition只有一个指针在做实际的移动,另一个指针一直保存的是插入的位置. class Solution { public: ListN