Loading...

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

示例 1:

输入: num1 = "2", num2 = "3"
输出: "6"

示例 2:

输入: num1 = "123", num2 = "456"
输出: "56088"

提示:

  • 1 <= num1.length, num2.length <= 200
  • num1 和 num2 只能由数字组成。
  • num1 和 num2 都不包含任何前导零,除了数字 0 本身。

解法

/**
 * 456*123
 * 进位 carry = 0
 * 第五位:6 * 3 + carry =                  8......1 (更新 carry = 1)
 * 第四位:5 * 3 + 6 * 2 + carry =          8......2 (更新 carry = 2)
 * 第三位:4 * 3 + 5 * 2 + 6 * 1 + carry =  0......3 (更新 carry = 3)
 * 第二位:4 * 2 + 5 * 1 + carry =          6......1 (更新 carry = 1)
 * 第一位:4 * 1 + carry =                  5......0 (更新 carry = 0)
 * 如果 carry!=1,将 carry 再放前一位、
 * 结果为 56088
 *
 * 对应下标:
 * i2 * j2
 * i1 * j2 + i2 * j1
 * i0 * j2 + i1 * j1 + i2 * j0
 * i0 * j1 + i1 * j0
 * i0 * j0
 *
 * @param num1
 * @param num2
 * @return
 */
public String mulity(String num1, String num2) {
    if ("0".equals(num1) || "0".equals(num2)){
        return "0";
    }
    int[] s1 = toIntArray(num1);
    int[] s2 = toIntArray(num2);
    int i = s1.length - 1;
    int j = s2.length - 1;
    String s = "";
    int carry = 0;
    for (int k = 0; k < s1.length + s2.length - 1; k++){
        int m = j;
        int sum = 0;
        // 循环次数(1,2,3,2,1)
        for (int l = i; i == 0 ? l <= j : l <= s1.length - 1; l++){
            sum = sum + (l >= s1.length ? 0 : s1[l]) * (m >= 0 ? s2[m--] : 0);
        }
        sum = sum + carry;
        carry = sum / 10;
        s = (sum % 10) + s;
        if (i == 0 && j > 0){
            j--;
        }
        if (i > 0){
            i--;
        }
    }
    return carry == 0 ? s : carry + s;
}

优化

public String mulity(String num1, String num2) {
    if ("0".equals(num1) || "0".equals(num2)){
        return "0";
    }
    int num1Length = num1.length();
    int num2Length = num2.length();
    int[] result = new int[num1Length + num2Length];
    for (int i = num1.length() - 1; i >= 0; i--){
        int a = num1.charAt(i) - '0';
        for (int j = num2.length() - 1; j >= 0; j--){
            int b = num2.charAt(j) - '0';
            // 求和
            int sum = result[i + j + 1] + a * b;
            // 当前位置取余数
            result[i + j + 1] = sum % 10;
            // 前一个位置取进位值
            result[i + j] = result[i + j] + sum / 10;
        }
    }
    // 第一个可能存在 0 的情况,去除
    StringBuilder s = new StringBuilder();
    for (int i = 0; i < result.length; i++){
        if (i == 0 && result[0] == 0){
            continue;
        }
        s.append(result[i]);
    }
    return s.toString();
}