Leetcode - Multiply Strings

![Uploading Paste_Image_697854.png . . .]

My code:

public class Solution {
    public String multiply(String num1, String num2) {
        if (num1 == null || num1.length() == 0 || num2 == null || num2.length() == 0)
            return null;
        int len = num1.length() + num2.length();
        int[] carry = new int[len];
        for (int i = num1.length() - 1; i >= 0; i--) {
            int temp1 = num1.charAt(i) - 48;
            for (int j = num2.length() - 1; j >= 0; j--) {
                int temp2 = num2.charAt(j) - 48;
                int mul = temp1 * temp2;
                int baseI = num1.length() - i - 1;
                int baseJ = num2.length() - j - 1;
                carry[baseI + baseJ] += mul;
                carry[baseI + baseJ + 1] += carry[baseI + baseJ] / 10;
                carry[baseI + baseJ] = carry[baseI + baseJ] % 10;
            }
        }
        if (carry[len - 2] >= 10) {
            carry[len - 1] = carry[len - 2] / 10;
            carry[len - 2] = carry[len - 2] % 10;
        }
        int resultLen = 0;
        if (carry[len - 1] == 0)
            resultLen = len - 1;
        else
            resultLen = len;
        String str = "";
        for (int i = resultLen - 1; i >= 0; i--)
            str += (char) (carry[i] + 48);
        for (int i = 0; i < resultLen; i++) {
            if (str.charAt(0) == '0') {
                if (i != resultLen - 1)
                    str = str.substring(1, str.length());
            }
            else
                break;
        }
        return str;
    }
    
    public static void main(String[] args) {
        Solution test = new Solution();
        System.out.println(test.multiply("1234", "0"));
    }
}

My test result:

这次作业思路不难,就是实现起来有点繁杂。具体如下。我的例子是

                       1 2 3 4 *
                          5 6 7
_________________________________
                       x x x x
                    x x x x
                 x x x x
-----------------------------
              x x x x x x x
我设置了一个carry数组来记录每一次乘法后的结果。
比如第一次是, 1 2 3 4 *
                   7
                  -------------
             8 6 3 8
那么 carry [7]----   7 6 5 4 3 2 1 0
               ->    0 0 0 0 8 6 3 8

然后第二轮相乘是, 1 2 3 4 *
                     6
-------------------------------

那么首先, 4 * 6 = 24; 再加上原先此位的carry[1] = 3; 即,
                 24 + 3 = 27; 将大于等于10的进位到前一位,
          2 -> 进位到前一位, 即 carry[baseI + baseJ + 1] = carry[baseI + baseJ] / 10;
          7 -> 保留在当前carry位。
于是,carry [7]----   7 6 5 4 3 2 1 0
                     0 0 0 0 8 6 3 8
                 ->  0 0 0 0 8 8 7 8

然后接着进行 3 * 6 = 18;那么carry变化为:
      carry [7]   ----   7 6 5 4 3 2 1 0
                         0 0 0 0 8 6 3 8
                         0 0 0 0 8 8 7 8
                   ->    0 0 0 0 10 6 7 8

2 * 6 = 12;
      carry [7]   ----   7 6 5 4 3 2 1 0
                         0 0 0 0 8 6 3 8
                         0 0 0 0 8 8 7 8
                         0 0 0 0 10 6 7 8
                  ->     0 0 0 2 2 6 7 8
1 * 6 = 6;
      carry [7]   ----   7 6 5 4 3 2 1 0
                         0 0 0 0 8 6 3 8
                         0 0 0 0 8 8 7 8
                         0 0 0 0 10 6 7 8
                         0 0 0 2 2 6 7 8
                ->       0 0 0 8 2 6 7 8

这个结果就是 1234 * 67的
之后多了一个5,也是以此类推。

**
总结:这次题目还好了。
记住了, 数字0 到字符0, 相差dec(48), OX30.
字符0 - 9 : OX30 - OX39 0 - 9
字符A - Z : OX41 - OX5A 65 - 90
字符a - z : OX61 - OX7A 97 - 122
所以,字符A到a 相差:相差dec(32), OX20.
**

Anyway, Good luck, Richardo!

My code:

public class Solution {
    public String multiply(String num1, String num2) {
        if (num1 == null || num1.length() == 0 || num2 == null || num2.length() == 0)
            return null;
        /** move insignificant digits to left, easy to be operated later */
        StringBuilder num1StrB = new StringBuilder(num1).reverse();
        StringBuilder num2StrB = new StringBuilder(num2).reverse();
        int[] ret = new int[num1.length() + num2.length()];
        /** calculate every multiplication, store results into every digit including carry */
        for (int i = 0; i < num1StrB.length(); i++) {
            for (int j = 0; j < num2StrB.length(); j++) {
                ret[i + j] += (num1StrB.charAt(i) - '0') * (num2StrB.charAt(j) - '0');
            }
        }
        
        StringBuilder sb = new StringBuilder();
        /** deal with carry. separate carry and mod from each digit */
        for (int i = 0; i < ret.length; i++) {
            int mod = ret[i] % 10;
            int carry = ret[i] / 10;
            if (i < ret.length - 1)
                ret[i + 1] += carry;
            sb.insert(0, mod); // move insignificant digits to the right
        }
        /** delete meaningless 0 on the left */
        while (sb.charAt(0) == '0' && sb.length() > 1) {
            sb.deleteCharAt(0);
        }
        return sb.toString();
    }
}

看了下之前自己写的,好复杂。
然后看了下网上的答案,自己写了下。这种题目还是看下答案。本身没多大意义。而且网上答案更加简洁易懂。
参考网址如下:
http://www.programcreek.com/2014/05/leetcode-multiply-strings-java/

就是先把每一位都乘一下,不进位,把每个结果都保存在相应的digit里面。
然后再统一处理进位。
最后,再除去左边多出来的一些0.
同时, StringBuilder sb.insert(0, mod);
就是在index = 0 处插入mod,如果已经有值了,就把现有值往右边移动。
deleteCharAt(0) 就是删除index = 0 处的值,然后不停地左移。

Anyway, Good luck, Richardo!

My code:

public class Solution {
    public String multiply(String num1, String num2) {
        if (num1 == null || num1.length() == 0 || num2 == null || num2.length() == 0) {
            return "";
        }
        
        int m = num1.length();
        int n = num2.length();
        int[] pos = new int[m + n];
        for (int i = m - 1; i >=0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
                int p1 = i + j;
                int p2 = i + j + 1;
                int sum = mul + pos[p2];
                pos[p1] += sum / 10;
                pos[p2] = sum % 10;
            }
        }
        
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < pos.length; i++) {
            if (!(sb.length() == 0 && pos[i] == 0)) {
                sb.append(pos[i]);
            }
        }
        if (sb.length() == 0) {
            sb.append('0');
        }
        return sb.toString();
    }
}

reference:
https://discuss.leetcode.com/topic/30508/easiest-java-solution-with-graph-explanation

直接看的答案。很简洁。
其实更像是找规律。

Anyway, Good luck, Richardo! -- 09/19/2016

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容