zoukankan      html  css  js  c++  java
  • LeetCode 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.
    • Converting the input string to integer is NOT allowed.
    • You should NOT use internal library such as BigInteger.

    【题目分析】

    给定两个用字符串表示的非负数字,用字符串的方式返回他们的乘积。要求不把字符串转换为整数,不适用BigInteger等内部library中的方法。


    【思路】

    如果做过了两个字符串表示的二进制数相加的题目,那么这个题目的思路很容易想到。

    这样的乘法我们只能转换成加法来实现,从乘数中取一位,与被乘数相乘,得到的结果在加到前面的结果上。这个过程涉及到多次字符与字符串相乘,还有多次字符串相加。

    在这个过程中我们需要注意的就是两个字符串相加是错位相加,比如:1234 * 1234

    乘数中的4与被乘数相乘的结果是4936

    乘数中的3与被乘数相乘的结果是3702

    相加的时候3702需要向前错一位。一种解决方法就是直接错位相加,另一种就在3702后面补0变为37020,则这两个数可以直接相加。

    我们采用补零的方法来使两个数对齐,背后的含义就是每向前一位就要多乘一个10。


    【java代码】

     1 public class Solution {
     2     public static String multiply(String num1, String num2) {
     3         if(num1.equals("0") || num2.equals("0"))
     4             return "0";
     5 
     6         String result = "0";
     7         for(int i = num1.length() - 1; i >= 0; i--){  //从乘数中取一个数
     8             int mulplier = num1.charAt(i) - 48;
     9             if (mulplier == 0) continue;
    10             StringBuilder cur = new StringBuilder();
    11             int count = num1.length() - 1 - i;
    12             for (int k = 0; k < count; k++)
    13                 cur.append(0);
    14             int carry = 0;
    15             for(int j = num2.length() - 1; j >= 0; j--){
    16                 int mulplited = num2.charAt(j) - 48;
    17                 int multiply = mulplited*mulplier + carry;
    18                 cur.append(multiply % 10);
    19                 carry = multiply / 10;
    20             }
    21             if(carry != 0) cur.append(carry);
    22 
    23             carry = 0;
    24             String addnum = cur.toString();
    25             StringBuilder newresult = new StringBuilder();
    26 
    27             int astart = 0, bstart = 0;
    28             while(astart < addnum.length() || bstart < result.length()){//当前结果与之前的结果相加
    29                 int sum = carry;
    30                 if(astart < addnum.length()) sum += addnum.charAt(astart++) - 48;
    31                 if(bstart < result.length()) sum += result.charAt(bstart++) - 48;
    32                 newresult.append(sum % 10);
    33                 carry = sum / 10;
    34             }
    35             if(carry != 0) newresult.append(carry);
    36             result = newresult.toString();
    37         }
    38         StringBuffer sb=new StringBuffer(result);
    39         sb=sb.reverse();
    40         return sb.toString();
    41     }
    42 }

     


    【思路2】

    上面的方法虽然通过了,但是时间复杂度比较高。有没有更好的方法呢?从leetcode上看到了大神的分析,很赞!

    `num1[i] * num2[j]` will be placed at indices `[i + j`, `i + j + 1]` 

    怎么样?是不是很赞呢!

    
    
  • 相关阅读:
    开源月刊《HelloGitHub》第 62 期
    手痒想写项目?我挑了 10 个开源项目送你
    有趣的开源项目集结完毕,HelloGitHub 月刊第 63 期发布啦!
    72 个网络应用安全实操要点,全方位保护 Web 应用的安全
    二十分钟学会Scratch图形化编程
    嵌入式linux与物联网进阶之路五:嵌入式驱动方式点亮LED
    嵌入式linux与物联网进阶之路四:嵌入式驱动开发思路
    嵌入式linux与物联网进阶之路三:根文件系统制作
    嵌入式linux与物联网进阶之路二:Linux内核编译
    嵌入式linux与物联网进阶之路一:U-Boot移植
  • 原文地址:https://www.cnblogs.com/liujinhong/p/5999642.html
Copyright © 2011-2022 走看看