【LeetCode43:字符串相乘(大数相乘)(Java实现)】

一、题目描述

1.题目内容

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
原题链接:https://leetcode.cn/problems/multiply-strings

2.样例

在这里插入图片描述

二、解决方案

1.算法流程

1)分析(竖式计算)

这道题本质上其实是经典的“大数相乘”问题,两个非负整数num1、num2比较大时,若进行乘法运算会导致“溢出”,所以要转换思想,将给定的整数转为字符串模拟手动竖式乘法运算。这里直接计算两个字符串的乘积结果,也就是省略了“大数相乘”中将整数转为字符串的步骤。
上小学的时候,我们都学过竖式乘法的计算过程,这里举个简单的例子,以此归纳出我们的算法流程:
num1=123,num2=456
从num2的个位开始,依次与num1的每一位进行乘法计算,满十进一,最后将每一位所得的值对应相加得到最终的运算结果。
下图中,红色填充表示num2每一位与num1对应的计算结果,蓝色字体表示进位(简单的竖式计算,相信大家都会),可看到因为最高位也有可能大于10,需要进位,所以最终结果的长度len(result)<=len(num1)+len(num2)
在这里插入图片描述
清晰了竖式计算的过程以后,实现“字符串相乘”就变得简单多了。

2)算法流程

  • 当num1或num2中有一个为“0”时结果直接为0,终止计算;
  • 创建一个整数数组result用于存储计算结果(数组元素默认初始化为0),其长度为lenOfNum1+lenOfNum2;
  • 从个位开始, 以num1为基础,逐次与num2的所有位进行乘积运算,得到对应位的计算值currentOfNum1*currentOfNum2,若currentOfNum1*currentOfNum2>=10,则需要进位;
  • 在计算的过程中,每得到一个值,就相应地记录在result的对应位置,以累加的方式进行元素的更新;

需要注意,计算过程中num1、num2为字符串形式,乘积结果使用整型数组来存储,在去除前导零后,将计算结果转换为字符串输出。
看代码吧,代码更清晰…

2.Java实现

1)核心代码

 public String multiply(String num1, String num2) {
 	// 当num1或num2中有一个为“0”时结果直接为0,终止计算
     if ((num1.length()==1&&num1.charAt(0)=='0')||(num2.length()==1&&num2.charAt(0)=='0')){
         return "0";
     }

     int lenOfNum1=num1.length();
     int lenOfNum2=num2.length();

	// 计算结果的最大长度为两个整数各自长度的和
     int[] result=new int[lenOfNum1+lenOfNum2];  // 创建一个整数数组用于存储计算结果

     for(int i=0;i<lenOfNum1;i++){
         int k=result.length-1-i;  // 从个位开始,依次计算
         int currentOfNum1=num1.charAt(lenOfNum1-1-i)-'0';  // num1此时对应位的字符
         for(int j=0;j<lenOfNum2;j++){
             int currentOfNum2=num2.charAt(lenOfNum2-1-j)-'0'; // num2此时对应位的字符
             result[k]+=currentOfNum1*currentOfNum2;  // 更新数组元素

             if(result[k]>=10){  // 判断此处是否需要进位
                 result[k-1]+=(result[k]/10);
                 result[k]%=10;
             }
             k--;  // 计算更高位的值
         }

     }

	// 去除前导0(最高位无进位时,则存在前导零的情况)
     int i=0;
     while (result[i]==0){
         i++;
     }
	// 拼接乘法运算结果(此时i指向计算结果中的第一个非0数字)
     StringBuilder resStr=new StringBuilder();
     while (i<result.length){
         resStr.append(result[i]);
         i++;
     }
     
     return resStr.toString();
 }

在这里插入图片描述

2)完整测试代码

import java.util.Arrays;

/**
 * LeetCode43:字符串相乘(模拟手算乘法)
 * */

public class MultiplyStrings {
    public static void main(String[] args) {
        MultiplySolution solution=new MultiplySolution();
        String num1 = "123";
        String num2 = "456";
        System.out.println(solution.multiply(num1,num2));
    }
}

class MultiplySolution {
    public String multiply(String num1, String num2) {
        if ((num1.length()==1&&num1.charAt(0)=='0')||(num2.length()==1&&num2.charAt(0)=='0')){
            return "0";
        }

        int lenOfNum1=num1.length();
        int lenOfNum2=num2.length();

        int[] result=new int[lenOfNum1+lenOfNum2];  // 创建一个整数数组用于存储计算结果

        for(int i=0;i<lenOfNum1;i++){
            int k=result.length-1-i;
            int currentOfNum1=num1.charAt(lenOfNum1-1-i)-'0';
            for(int j=0;j<lenOfNum2;j++){
                int currentOfNum2=num2.charAt(lenOfNum2-1-j)-'0';
                result[k]+=currentOfNum1*currentOfNum2;

                if(result[k]>=10){
                    result[k-1]+=(result[k]/10);
                    result[k]%=10;
                }
                k--;
            }

        }

        // 处理计算结果的前导零
        int i=0;
        while (result[i]==0){
            i++;
        }

        // 拼接乘法运算结果(此时i指向计算结果中的第一个非0数字)
        StringBuilder resStr=new StringBuilder();
        while (i<result.length){
            resStr.append(result[i]);
            i++;
        }
//        System.out.println(Arrays.toString(result));
        return resStr.toString();
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NorthSmile

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值