43. Multiply Strings

题目:

Given two numbers represented as strings, return multiplication of the numbers as a string.

Note: The numbers can be arbitrarily large and are non-negative.

链接:  http://leetcode.com/problems/multiply-strings/

题解: 

大数乘法,建立一个数组,保存每一位乘出来的数字,然后再保存成字符串就可以了。跟add two number一类的很像。

Time Complexity - O(m * n), Space Complexity - O(m + n)。

public class Solution {
    public String multiply(String num1, String num2) {          //Big Integer multiplying
        if(num1 == null || num2 == null || num1.length() == 0 || num2.length() == 0)
            return "";
        int num1Len = num1.length(), num2Len = num2.length();
        int[] resArr = new int[num1Len + num2Len];
        
        for(int i = num1Len - 1; i >= 0; i--) {
            for(int j = num2Len - 1; j >= 0; j--) {
                int index = (num1Len - 1 - i) + (num2Len - 1 - j);      //stored the data increasingly
                resArr[index] += (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
                resArr[index + 1] += resArr[index] / 10;
                resArr[index] %= 10;
            }
        }
        
        StringBuilder res = new StringBuilder();
        
        for(int i = resArr.length - 1; i > 0; i--) {
            if(res.length() == 0 && resArr[i] == 0)
                continue;
            res.append(resArr[i]);
        }
        
        res.append(resArr[0]);
        return res.toString();
    }
}

 

二刷:

一刷的逻辑相当不清楚啊...当时怎么糊弄过去的...现在就好一些。主要思路是:

  1. 两数相乘,结果的长度不会大于两数长度和m + n,所以一开始我们开一个int[] res = new int[m + n]
  2. 接下来对num1和num2做一个双重循环从后向前遍历
    1. 当前的 digit1 = num1.charAt(i) - '0',  digit2 = num2.charAt(j) - '0'
    2. 这时我们可以更新当前res[i + j + 1]的这个位置为原来存在这一位置上的值再加上新的值digits 1 * digit2,简略一下就是 res[i + j + 1] += digits 1 * digit2 
    3. 接下来根据res[i + j + 1]的新值,我们可以更新高一位的res[i + j],  res[i + j] += res[i + j + 1] / 10,就是本来的值加上进位
    4. 最后我们再用res[i + j + 1] %= 10求出这一位置进位后剩下的digit
  3. 求出res数组之后我们可以建立一个StringBuilder sb,来从头遍历数组,求出最终结果
    1. 要注意的是当sb.length() == 0并且res[i] = 0时,这时候是开头的0值,需要跳过
    2. 假如遍历完毕以后sb.length()依然等于0, 我们返回"0"

Java:

Time Complexity - O(mn),  Space Complexity - O(m + n)

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

 

题外话:

1/25/2016

NWK到JSQ的Path还没有修好,所以今天周一WFH。需要提高刷题速度了,不然难以按照进度完成。 周五晚海投了50份简历试试水,估计不内推还是很难拿到回应。

 

三刷:

方法和一刷二刷一样。就是先开一个数组,把num1和num2每个digit的乘积保存起来, 再进行进位操作。

要注意的是,在计算乘积的时候,num1的第i位和num2的第j位的乘积,要保存在数组的product[i + j + 1]这个位置里。用两个例子 "100 * 100"和"99 * 99"一计算就很容易能发现这个规律。 还有一点就是,最后乘积全为0的话要返回"0"。  去除乘积串前部的"0"可以用条件 if (digit != 0 || sb.length() > 0)。

更好的方法应该是Karatsuba multiply,利用Divide and Conquer将复杂度降低到nlog2。留给以后了。

Java:

public class Solution {
    public String multiply(String num1, String num2) {
        if (num1 == null || num2 == null || num1.length() == 0 || num2.length() == 0) return "0";
        int len1 = num1.length(), len2 = num2.length();
        int[] product = new int[len1 + len2];
        for (int i = len1 - 1; i >= 0; i--) {
            int digit1 = num1.charAt(i) - '0';
            for (int j = len2 - 1; j >= 0; j--) {
                int digit2 = num2.charAt(j) - '0';
                product[i + j + 1] += digit1 * digit2;
            }
        }
        
        for (int i = product.length - 1; i >= 1; i--) {
            product[i - 1] += product[i] / 10;
            product[i] %= 10;
        }
        
        StringBuilder sb = new StringBuilder();
        for (int digit : product) {
            if (digit != 0 || sb.length() > 0) sb.append(digit);
        }
        if (sb.length() == 0) sb.append(0);
        
        return sb.toString();
    }
}

 

Update: 也可以像二刷一样把进位操作写到一个循环体里

public class Solution {
    public String multiply(String num1, String num2) {
        if (num1 == null || num2 == null || num1.length() == 0 || num2.length() == 0) return "0";
        int len1 = num1.length(), len2 = num2.length();
        int[] product = new int[len1 + len2];
        for (int i = len1 - 1; i >= 0; i--) {
            int digit1 = num1.charAt(i) - '0';
            for (int j = len2 - 1; j >= 0; j--) {
                int digit2 = num2.charAt(j) - '0';
                product[i + j + 1] += digit1 * digit2;
                product[i + j] += product[i + j + 1] / 10;
                product[i + j + 1] %= 10;    
            }
        }
        
        StringBuilder sb = new StringBuilder();
        for (int digit : product) {
            if (digit != 0 || sb.length() > 0) sb.append(digit);
        }
        if (sb.length() == 0) sb.append(0);
        
        return sb.toString();
    }
}

 

 

Reference:

http://www.cnblogs.com/springfor/p/3889706.html

https://leetcodenotes.wordpress.com/2013/10/20/leetcode-multiply-strings-%E5%A4%A7%E6%95%B4%E6%95%B0%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B9%98%E6%B3%95/

https://leetcode.com/discuss/71593/easiest-java-solution-with-graph-explanation

https://leetcode.com/discuss/26602/brief-c-solution-using-only-strings-and-without-reversal

https://leetcode.com/discuss/33951/ac-solution-in-java-with-explanation

https://leetcode.com/discuss/29364/clear-java-solution-without-reversal

http://introcs.cs.princeton.edu/java/99crypto/Karatsuba.java.html

https://d396qusza40orc.cloudfront.net/algo1/slides/algo1-intro3_typed.pdf

posted @ 2015-04-17 23:23  YRB  阅读(855)  评论(0编辑  收藏  举报