Leetcode - Multiply String

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.

[分析] Naive的做法是模拟笔算乘法操作,从高位到低位的顺序将num2 上的每一位同num1 相乘,由于运算顺序从高到低,每次运算时将上一次运算结果后加0,(相当于*10)后同本次乘积结果加和。 高效做法(Method 2)思路:num1 * num2, num2上的每一位依次和num1中的每一位相乘,num2的个位同num1的个位相乘结果包含在最终乘积的个位上,同理num2的个位同num1的十位相乘结果包含在最终乘积的十位上,num2的十位同num1的个位相乘结果也包含在最终乘积的十位上,一般的,num2的第 i 位 同num1的第 j 位相乘结果包含在最终乘积的第 i + j 位,遍历两个数的每一位,可以得到最终乘积各位上的结果。这样得到的乘积各位上可能是两位数,因此还需要处理使得乘积结果各位上为单个数字,处理方式就是依次进位。Method 1有O(m * n)次 *、\、% 以及字符串append操作, O(m * (m + n))次 +, append操作,而Method 2仅有O(m * n)次 *、+ 以及O(m + n)次 \、%、append操作,我们知道除法和取模是最耗时的,所以前者超时也就不难怪了。

    // method 2: 
    public String multiply(String num1, String num2) {
        if (num1 == null || num2 == null || num1.length() == 0 || num2.length() == 0)
            return null;
        if (num1.length() < num2.length())
            return multiply(num2, num1);
        if (num2.equals("0")) return "0";
        if (num2.equals("1")) return num1;
        int[] result = new int[num1.length() + num2.length() - 1];
        for (int i = num2.length() - 1; i >= 0; i--) {
            int digit1 = num2.charAt(i) - '0';
            for (int j = num1.length() - 1; j >= 0; j--) {
                result[i + j] += digit1 * (num1.charAt(j) - '0');
            }
        }
        int carry = 0;
        for (int i = result.length - 1; i >= 0; i--) {
            result[i] += carry;
            carry = result[i] / 10;
            result[i] %= 10;
        }
        StringBuilder val = new StringBuilder();
        if (carry > 0)
            val.append(carry);
        for (int i = 0; i < result.length; i++)
            val.append(result[i]);
        return val.toString();
    }
    // method 1 : 
    public String multiply1(String num1, String num2) {
        if (num1 == null || num2 == null || num1.length() == 0 || num2.length() == 0)
            return null;
        String result = "";
        for (int i = 0; i < num2.length(); i++) {
            result = add(result + '0', multiOneDigit(num1, num2.charAt(i) - '0'));
        }
        return result;
    }
    private String add(String num1, String num2) {
        if (num1.length() < num2.length()) {
            String tmp = num2;
            num2 = num1;
            num1 = tmp;
        }
        StringBuilder sum = new StringBuilder();
        int carry = 0, val = 0;
        int i = num1.length() - 1, j = num2.length() - 1;
        while (j >= 0) {
            val = (num1.charAt(i) - '0') + (num2.charAt(j) - '0');
            sum.append(val - 10); // val % 10
            carry = val >= 10 ? 1 : 0; // val / 10
            i--; j--;
        }
        while (i >= 0) {
            val = (num1.charAt(i--) - '0') + carry;
            sum.append(val - 10);
            carry = val >= 10 ? 1 : 0;
        }
        if (carry > 0) sum.append(carry);
        return sum.reverse().toString();
    }
    private String multiOneDigit(String num1, int num2) {
        StringBuilder result = new StringBuilder();
        int carry = 0, val = 0;
        for (int i = num1.length() - 1; i >= 0; i--) {
            val = (num1.charAt(i) - '0') * num2 + carry;
            result.append(val % 10);
            carry = val / 10;
        }
        if (carry > 0)
            result.append(carry);
        return result.reverse().toString();
    }

猜你喜欢

转载自likesky3.iteye.com/blog/2219625