风雨雾凇 风雨雾凇
首页
  • 服务端

    • golang
  • 其他

    • leetcode
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

风雨雾凇

技术小渣渣
首页
  • 服务端

    • golang
  • 其他

    • leetcode
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • golang

  • 技术文档

  • GitHub技巧

  • Nodejs

  • 博客搭建

  • leetcode

    • 两数之和-1
    • 无重复字符的最长子串-3
    • 整数翻转-7
    • 回文数-9
    • 13-罗马数字转整数
    • 最长公共前缀
    • 3Sum
    • Valid Parentheses
    • Merge Two Sorted Lists
    • Remove Duplicates from Sorted Array
    • Remove Element
    • Implement strStr()
    • Search Insert Position
    • Count and Say
    • 字符串相乘
      • 思路
      • 代码
      • 官方最佳解答
    • Maximum Subarray
    • Length of Last Word
    • Plus One
    • Add Binary
    • Sqrt(x)
    • 翻转字符串里的单词
    • 字符串的排列
  • 机器学习

  • 技术
  • leetcode
风雨雾凇
2018-12-27
目录

字符串相乘

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

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

示例 2:
输入: num1 = "123", num2 = "456"
输出: "56088"
1
2
3
4
5
6
7

说明:

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

题目链接:点击这里~ (opens new window)

# 思路

由于 num1 和 num2 长度最大为 110,故两数相乘的长度最大 110 * 110 位,long 为8字节 所能表示的最大长度为 2^64,所能表示最大长度远远小于目标位数,故 将字符串转为int类型后在做运算在转回字符串的方法行不通。

研究乘法计算发现规律, 以 123 *456 = 56088 举例:

1 2 3
* 4 5 6
1 * 6 = 6 2 * 6 = 12 3 * 6 = 18
1 * 5 = 5 2 * 5 = 10 3 * 5 = 15
4 * 1 = 4 4 * 2 = 8 4 * 3 = 12
4 5 + 8 = 13 6 + 10 + 12 = 28 12 + 15 =27 18
40000 10000 + 3000 2000 + 800 200 + 70 10 + 8
40000 + 10000 3000 +2000 800 + 200 70 + 10 8
5 6 0 8 8

则可以通过逐位相乘在相加的形式完成大数的乘法运算。

# 代码

class Solution {
    public String multiply(String num1, String num2) {
int len1 = num1.length();
        int len2 = num2.length();
        // 获得最大位数建立数组
        int[] res = new int[len1 + len2];

        // 遍历计算每位对应的数值 从最低位开始
        int n1, n2;
        for (int i = len1 - 1; i >= 0; i--) {
            n1 = num1.charAt(i) - '0';
            for (int j = len2 - 1; j >= 0; j--) {
                n2 = num2.charAt(j) - '0';
                res[i + j + 1] += n1 * n2;
                // 如果大于10则向前进位
                if(res[i + j + 1] >= 10 ){
                    res[i + j] += res[i + j + 1] / 10;
                    res[i + j + 1] %= 10;
                }
            }
        }

        // 将int数组转为字符串
        StringBuilder stringBuffer = new StringBuilder(len1 + len2);
        boolean flag = true;
        for (int n : res){
            if(flag){
                if(n != 0){
                    flag = false;
                }else {
                    continue;
                }
            }
            stringBuffer.append(n);
        }
        return stringBuffer.toString().isEmpty() ? "0" : stringBuffer.toString();

    }
}
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

难点:注意进位问题

# 官方最佳解答

class Solution {
    public String multiply(String num1, String num2) {
		if(num1.isEmpty() || num2.isEmpty() 
           ||(num1.length() == 1 && num1.charAt(0) == '0') 
           || (num2.length() == 1 && num2.charAt(0) == '0'))
			return "0";
		int len1 = num1.length();
		int len2 = num2.length();
		int[] ans = new int[len1 + len2 + 1];
		for(int i = 0 ; i < len1;i++) {
			int a = num1.charAt(i) - '0';
			for(int j = 0; j < len2; j++) {
				int b = num2.charAt(j) - '0';
				ans[len1 + len2 - i - j - 2] += a * b ;
			}
		}
		StringBuffer res = new StringBuffer();		
		for(int i = 0; i < len1 + len2   ;i++) {
			res.append(ans[i] % 10);
			ans[i + 1] += ans[i] / 10;
		}
		String result = res.reverse().toString();
		if(result.startsWith("0"))
			result = result.substring(1, len1 + len2);
		return result;
	}  
}
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
编辑 (opens new window)
#leetcode#每日训练#算法#面试#学习笔记
上次更新: 2023/02/17, 16:53:03
Count and Say
Maximum Subarray

← Count and Say Maximum Subarray→

最近更新
01
builtin
02-12
02
导读
02-12
03
13-罗马数字转整数
01-30
更多文章>
Theme by Vdoing | Copyright © 2017-2023 风雨雾凇 | 粤ICP备16018321号-2
博客内容遵循署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式