NC10 大数乘法

描述

以字符串的形式读入两个数字,编写一个函数计算它们的乘积,以字符串形式返回。

数据范围: 读入的数字大小满足 0 \le n \le 10^{1000}0≤n≤101000
要求:空间复杂度 O(n)O(n),时间复杂度 O(n^2)O(n2)

示例1

输入:

"11","99"

复制返回值:

"1089"

复制说明:

11*99=1089 

示例2

输入:

"1","0"

复制返回值:

"0"

题解 | #大数乘法#

发表于 2021-08-13 21:11:19

public class Solution10 {

复制代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

public String solve(String s, String t) {

    //数字数组:高位在数组左,低位在数组右,处理需注意

    int[] arr1 = new int[s.length()];

    int[] arr2 = new int[t.length()];

    for (int i = 0; i < s.length(); i++) {

        arr1[i] = s.charAt(i) - '0';

    }

    for (int i = 0; i < t.length(); i++) {

        arr2[i] = t.charAt(i) - '0';

    }

    return getRes(arr1, arr2);

}

private String getRes(int[] arr1, int[] arr2) {

    int len1 = arr1.length;

    int len2 = arr2.length;

    //开辟结果数组,结果长度最大为len1+len2

    int[] result = new int[len1 + len2];

    /**

     * 开始计算先不考虑进位,每次结果存放在result[i+j+1]

     * 为什么是i+j+1?

     * 因为结果数组计算处理高位在数组左,低位在数组右

     * i+j+1实际是往低位存,这样后面进位处理才正确

     */

    //字符串的0就是值的最高位,因为字符串的低位就是值的高位

    for (int j = 0; j < len2; j++) {

        for (int i = 0; i < len1; i++) {

            //这里注意是将乘积的高位(也就是字符串的0位开始乘)从数组的低位开始存,也就是最左边

            //所以将来遍历数组的低位存放的就是结果值的低位

            //数组的高位存放的就是结果值的低位

            result[i + j + 1] += arr1[i] * arr2[j];

        }

    }

    //计算该进位和结果数,从最低位(数组末尾)向前计算

    //因为数组低位也就是最左边反而是值的高位

    int carry = 0;

    //注意数组左边是高位,数组右边是低位,从右到左

    for (int i = result.length - 1; i >=0 ; i--) {

        int sum = result[i] + carry;

        carry = sum / 10;

        result[i] = sum % 10;

    }

    /**

     * 转为String,需要无视前置0

     * 如果最终builder长度为0,结果应该输出“0”

     */

    StringBuilder builder = new StringBuilder();

    //最左边就是最高位,先把高位都是0的排除掉

    int curPos = 0;

    /**

     * 这一步判断一个条件都不能少

     * 否则 "0" ✖ ️"0"就会曝出数组越界异常

     * 因为结果等于0 ,curPos++一定会越界

     */

    while (curPos < result.length && result[curPos] == 0) {

        curPos++;

    }

    for (int i = curPos; i < result.length; i++) {

        builder.append(result[i]);

    }

    if (builder.length() == 0) {

        return "0";

    }

    return builder.toString();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值