Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

https://leetcode.com/problems/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.

解题思路:

大数的乘法,乘数和被乘数都是正数,其实按照题目的意思应该限定在正整数才对。

就开始想到按位来一个个计算,那么需要两个方法。一个是,大数的乘法,一个是大数的加法。细节就不说了,在加法的方法里,用递归处理剩余多出位数的问题,但是最开始的递归返回条件不能忘记。

public class Solution {
    public String multiply(String num1, String num2) {
        if(num1.equals("0") || num2.equals("0")) {
            return "0";
        }
        // //保证num2的长度不比num1大
        // if(num1.length() < num2.length()) {
        //     String temp = num1;
        //     num1 = num2;
        //     num2 = temp;
        // }
        String result = "0";
        for(int i = num2.length() - 1; i >= 0; i--) {
            String result_here = "";
            int multi = 0, here = 0, carry = 0;
            // 乘法计算的时候,错位后面加上0
            for(int k = 0; k < num2.length() - 1 - i; k++) {
                result_here += "0";
            }
            for(int j = num1.length() - 1; j >= 0; j--) {
                multi = (num1.charAt(j) - '0') * (num2.charAt(i) - '0');
                here = (carry + multi) % 10;
                carry = (carry + multi) / 10;
                result_here = String.valueOf(here) + result_here;
            }
            // 乘到最前面一位,结束的时候再在前面加上进位
            if(carry > 0) {
                result_here = String.valueOf(carry) + result_here;
            }
            // 每一位的乘法的和相加
            result = plus(result, result_here);
        }
        return result;
    }
    
    public String plus(String num1, String num2) {
        if((num1 == null || num1.length() == 0) && num2.equals("0")) {
            return "";
        }
        if(num1 == null || num1.length() == 0 || num1.equals("0")) {
            return num2;
        }
        if(num2.equals("0")) {
            return num1;
        }
        String result = "";
        // int length = Math.min(num1.length(), num2.length());
        int sum = 0, here = 0, carry = 0;
        int i = num1.length() - 1, j = num2.length() - 1;
        while (i >= 0 && j >= 0) {
            sum = (num1.charAt(i) - '0') + (num2.charAt(j) - '0');
            here = (carry + sum) % 10;
            carry = (carry + sum) / 10;
            result = String.valueOf(here) + result;
            i--;
            j--;
        }
        //计算比较长的数字的前面的部分,加上carry,再接在前面算出的result的前面,递归
        if(i < 0) {
            result = plus(num2.substring(0, num2.length() - num1.length()), String.valueOf(carry)) + result;
        } else {
            result = plus(num1.substring(0, num1.length() - num2.length()), String.valueOf(carry)) + result;
        }
        return result;
    }
}

这么做的时间复杂度是O(m*n)。

看了网友的另一种解法,更为简洁。

1. 我们令num1的长度为m,num2的长度为n,那么乘积的结果要么是m+n位,要么是m+n-1位(没有进位)。

2. num1的第i位和num2的第j位相乘,在结果中位于第i+j+1位。当然,如果没有进位的话,最后结果的第一位(i==0)是0。

这种解法不是从乘数或者被乘数开始计算,而是从乘积考虑,计算乘积每一位的结果。

public class Solution {
    public String multiply(String num1, String num2) {
        int[] result = new int[num1.length() + num2.length()];
        for(int i = num1.length() - 1; i >= 0; i--) {
            for(int j = num2.length() - 1; j >= 0; j--) {
                int product = (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
                int sum = result[i + j + 1] + product;
                result[i + j + 1] = sum % 10;   //乘积结果
                result[i + j] += sum / 10;  //进位
            }
        }
        int start = 0;
        while(start < result.length && result[start] == 0){
            start++;
        }
        if(start > result.length - 1) {
            return "0";
        }
        String res = "";
        while(start < result.length) {
            res += String.valueOf(result[start]);
            start++;
        }
        return res;
    }
}

 

posted on 2015-05-09 19:14  NickyYe  阅读(158)  评论(0编辑  收藏  举报