Leetcode43. 字符串相乘

Leetcode43. 字符串相乘

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

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

示例 2:

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

说明:
num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

方法一:
和字符串相加类似:
Leetcode415. 字符串相加
题解:
竖式运算思想,以 num1 为 123,num2 为 456 为例分析:
在这里插入图片描述
遍历 num2 每一位与 num1 进行相乘,将每一步的结果进行累加。
注意:
num2 除了第一位的其他位与 num1 运算的结果需要 补0
计算字符串数字累加其实就是 415. 字符串相加
方法二:
该算法是通过两数相乘时,乘数某位与被乘数某位相乘,与产生结果的位置的规律来完成。具体规律如下:

  • 乘数 num1 位数为 M,被乘数 num2 位数为 N, num1 x num2 结果 res 最大总位数为 M+N
  • num1[i] x num2[j] 的结果为 tmp(位数为两位,“0x”,"xy"的形式),其第一位位于 res[i+j],第二位位于 res[i+j+1]。
    结合下图更容易理解
    在这里插入图片描述
    java代码:
    方法一:
public static String multiply(String s1, String s2) {
        if (s1 == "0" || s2 == "0") return "0";
        String result = "0";
        for (int i = s2.length() - 1; i >= 0; i--) {

            StringBuffer buffer = new StringBuffer();

            for (int j = s2.length() - 1 - i; j > 0; j--) {
                buffer.append(0);
            }
            int n2 = s2.charAt(i) - '0';
            int carry = 0;
            int len = s1.length() - 1;
            while (len >= 0 || carry > 0) {
                int n1 = len < 0 ? 0 : s1.charAt(len) - '0';
                int a = n1 * n2 + carry;
                buffer.append(a % 10);
                carry = a / 10;
                len--;
            }
            result = addStrings(result, buffer.reverse().toString());
        }

        return result;
    }
public static String addStrings(String s1, String s2) {

        int i = s1.length() - 1;
        int j = s2.length() - 1;
        StringBuffer buffer = new StringBuffer();
        int n1, n2;
        int carry = 0;
        while (i >= 0 || j >= 0) {
            if (i >= 0) {
                n1 = s1.charAt(i) - '0';
            } else {
                n1 = 0;
            }
            if (j >= 0) {
                n2 = s2.charAt(j) - '0';
            } else {
                n2 = 0;
            }

            int num = n1 + n2 + carry;
            carry = num / 10;
            int res = num % 10;
            buffer.append(res);
            i--;
            j--;
        }
        if (carry > 0) buffer.append(carry);
        return buffer.reverse().toString();
    }

方法二:

public static String multiply2(String s1, String s2) {
        if (s1 == "0" || s2 == "0") return "0";
        int[] res = new int[s1.length() + s2.length()];
        for (int i = s1.length() - 1; i >= 0; i--) {
            for (int j = s2.length() - 1; j >= 0; j--) {
                int n1 = s1.charAt(i) - '0';
                int n2 = s2.charAt(j) - '0';
                int num = n1 * n2 + res[i + j + 1];
                res[i + j + 1] = num % 10;
                res[i + j] = res[i + j] + num / 10;
            }
        }

        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < res.length; i++) {
            if (i == 0 && res[i] == 0) continue;
            buffer.append(res[i]);
        }

        return buffer.toString();
    }

scala代码:
方法一:

/**
    *
    * @param num1
    * @param num2
    * @return
    */
  def multiply(num1: String, num2: String): String = {

    var result = "0"
    if (num1 != "0" && num2 != "0") {
      //
      for (i <- 0 until num2.length reverse) {
        //进位
        var carry = 0
        // 保存 num2 第i位数字与 num1 相乘的结果
        val temp = new StringBuilder()
        //对nums2中的每一位补0
        for (j <- 0 until num2.length - 1 - i) {
          temp.append(0)
        }

        val n2 = num2(i) - '0'

        var k = num1.length - 1
        while (k >= 0 || carry != 0) {
          val n1 = if (k < 0) 0 else num1.charAt(k) - '0'
          val product = (n1 * n2 + carry) % 10
          temp.append(product)
          carry = (n1 * n2 + carry) / 10
          k = k - 1
        }
        //将当前结果与新计算的结果求和作为新的结果
        result = addStrings(result, temp.reverse.toString())
      }
    }
    result
  }


  def addStrings(str1: String, str2: String): String = {

    val builder = new StringBuilder()
    var carry = 0
    var i = str1.length - 1
    var j = str2.length - 1
    while (i >= 0 || j >= 0 || carry != 0) {
      val n1 = if (i < 0) 0 else str1.charAt(i) - '0'
      val n2 = if (j < 0) 0 else str2.charAt(j) - '0'
      val product = (n1 + n2 + carry) % 10
      builder.append(product)
      carry = (n1 + n2 + carry) / 10
      i = i - 1
      j = j - 1
    }
    builder.reverse.toString()

  }

方法二:

/**
    *
    * @param num1
    * @param num2
    * @return
    */
  def multiply2(num1: String, num2: String): String = {

    if (num1 == "0" || num2 == "0") {
      "0"
    } else {
      val arr = new Array[Int](num1.length + num2.length)
      for (i <- 0 until num1.length reverse) {
        for (j <- 0 until num2.length reverse) {
          val n1 = num1.charAt(i) - '0'
          val n2 = num2.charAt(j) - '0'
          val sum = n1 * n2 + arr(i + j + 1)
          arr(i + j + 1) = sum % 10
          arr(i + j) = arr(i + j) + sum / 10
        }
      }
      val str = new StringBuilder()
      for (i <- 0 until arr.length) {
        //去掉首位为0的情况
        breakable {
          if (i == 0 && arr(i) == 0) {
            break()
          }
          str.append(arr(i))
        }

      }
      str.toString()
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值