LeetCode 题目 43:字符串相乘 多种算法分析对比 【python】

简介: LeetCode 题目 43:字符串相乘 多种算法分析对比 【python】

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。

会一些的技术:数据分析、算法、SQL、大数据相关、python

欢迎加入社区:码上找工作

作者专栏每日更新:

LeetCode解锁1000题: 打怪升级之旅

python数据分析可视化:企业实战案例

备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

本文将详细介绍解决LeetCode题目43 "字符串相乘"的三种方法:模拟乘法手算、Karatsuba算法,以及快速傅立叶变换(FFT)方法。这些方法逐渐提升计算大数乘法的效率。

问题描述

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

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

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

方法一:模拟乘法手算

解题步骤

  1. 初始化结果数组:长度为两数长度之和,用于存放乘积的每一位。
  2. 逐位相乘:外层和内层循环分别遍历两个字符串的每一位数字,相乘后加到结果数组的相应位置。
  3. 处理进位:从结果数组的末尾开始向前处理进位。
  4. 输出结果:将结果数组转换为字符串,注意去除前导零。

代码示例

def multiply(num1: str, num2: str) -> str:
    if num1 == "0" or num2 == "0":
        return "0"
    
    m, n = len(num1), len(num2)
    # 结果数组,长度为m+n,最大位数的情况
    result = [0] * (m + n)
    
    # 从后向前遍历两个数字
    for i in range(m-1, -1, -1):
        for j in range(n-1, -1, -1):
            # 两数对应位相乘,并加上之前该位的累积结果
            mul = (ord(num1[i]) - ord('0')) * (ord(num2[j]) - ord('0'))
            # 求和位置,即数组中对应的索引
            p1, p2 = i + j, i + j + 1
            # 总和
            sum = mul + result[p2]
            
            # 设置当前位和进位
            result[p1] += sum // 10
            result[p2] = sum % 10
    
    # 将结果数组转换为字符串,首先去除数组前端的0
    while len(result) > 1 and result[0] == 0:
        result.pop(0)
    
    return ''.join(map(str, result))

算法分析

  • 时间复杂度: O(M*N), 其中 M 和 N 是输入数字的长度。
  • 空间复杂度: O(M+N), 用于存储计算结果。

方法二:Karatsuba 算法

解题步骤

Karatsuba 算法是一种分治算法,它通过将大数运算分解为较小数的运算来减少乘法操作的总数。这种方法利用了数学上的巧妙技巧来加速大整数的乘法过程。

  1. 分割数字:将每个数分割成两部分,例如,将数字123456分割为123和456,分割点通常在中间,或者靠近中间。
  2. 递归计算
  • 设两个大数为 ( a ) 和 ( b ),分别分割为 ( a1, a0 ) 和 ( b1, b0 ),其中 ( a1, b1 ) 是高位部分,( a0, b0 ) 是低位部分。
  • 计算三个关键乘积:
  • ( p1 = a1 * b1 )
  • ( p2 = a0 * b0 )
  • ( p3 = (a1 + a0) * (b1 + b0) )
  • 结果通过组合这三个乘积获得:( result = p1 * 10^2m + (p3 - p1 - p2) * 10^m + p2 ),其中 ( m ) 是分割的位数。
  1. 合并结果:根据上述公式组合得到最终的乘积。

完整的规范代码

def karatsuba(num1, num2):
    if len(num1) < 10 or len(num2) < 10:  # 为简化计算,小于10位数直接转为整数计算
        return str(int(num1) * int(num2))
    # 将输入数字补齐为等长
    max_len = max(len(num1), len(num2))
    num1 = num1.zfill(max_len)
    num2 = num2.zfill(max_len)
    
    # 计算分割位数
    half_len = max_len // 2
    
    # 高位和低位数
    high1, low1 = num1[:-half_len], num1[-half_len:]
    high2, low2 = num2[:-half_len], num2[-half_len:]
    
    # 递归计算p1, p2, p3
    z0 = karatsuba(low1, low2)
    z1 = karatsuba(str(int(low1) + int(high1)), str(int(low2) + int(high2)))
    z2 = karatsuba(high1, high2)
    
    # 组合结果
    result = str(int(z2) * 10**(2*half_len) + (int(z1) - int(z2) - int(z0)) * 10**half_len + int(z0))
    return result
# 示例调用
print(karatsuba("123456789", "987654321"))  # 输出: "121932631112635269"

算法分析

  • 时间复杂度: (O(n^1.585,其中 ( n ) 是输入数字的位数。这比传统的 (O(n^2)) 方法要快。
  • 空间复杂度: (O(log n)),主要空间消耗在递归调用栈上。

优点

  • 效率提升:对于大数乘法,Karatsuba算法提供了显著的速度优势。
  • 适用于大数:非常适合处理大规模数字,常用于计算机科学和大数据领域。

缺点

  • 实现复杂度:相比简单的逐位乘法,Karatsuba算法实现更为复杂,特别是在处理数字分割和递归方面。
  • 边界处理:在实际实现时,处理数字长度和递归的终止条件需要小心设计。

Karatsuba算法是大数乘法的一个有效优

化方法,尤其适合于需要快速乘法计算的应用,如加密和数值模拟。通过利用数学的分治技巧,它能够有效地减少计算复杂度,提升计算性能。

方法三:快速傅立叶变换(FFT)

解题步骤

快速傅立叶变换(FFT)是一种高效的数字乘法方法,适用于大数乘法。其基本思想是将整数乘法转换为多项式乘法问题,利用FFT快速进行点值计算。

  1. 数位扩展与对齐:首先将数字字符串转换为逆序的整数数组,并扩展长度至2的幂次方,以满足FFT的要求。
  2. 应用FFT转换:将数字数组通过FFT转换到频域,即计算其点值表示。
  3. 点值乘法:将两个数的点值数组对应位置相乘,这相当于多项式乘法的点值表示。
  4. 逆FFT变换:应用逆FFT将乘积的点值表示转换回系数表示,即得到时间域的多项式系数。
  5. 处理进位与格式化:将逆FFT的结果处理进位,然后转换为字符串输出。

完整的规范代码

使用numpy库来实现FFT和逆FFT,这里假设已经安装了numpy。

import numpy as np
def fft(a):
    n = len(a)
    if n == 1:
        return a
    even = fft(a[0::2])
    odd = fft(a[1::2])
    T = [np.exp(-2j * np.pi * k / n) * odd[k] for k in range(n // 2)]
    return [even[k] + T[k] for k in range(n // 2)] + [even[k] - T[k] for k in range(n // 2)]
def ifft(a):
    n = len(a)
    if n == 1:
        return a
    even = ifft(a[0::2])
    odd = ifft(a[1::2])
    T = [np.exp(2j * np.pi * k / n) * odd[k] for k in range(n // 2)]
    return [(even[k] + T[k]) / 2 for k in range(n // 2)] + [(even[k] - T[k]) / 2 for k in range(n // 2)]
def multiply(num1, num2):
    n = 1
    while n < max(len(num1), len(num2)):
        n <<= 1
    n <<= 1
    a = np.array([int(x) for x in num1[::-1]] + [0] * (n - len(num1)), dtype=complex)
    b = np.array([int(x) for x in num2[::-1]] + [0] * (n - len(num2)), dtype=complex)
    
    fa = fft(a)
    fb = fft(b)
    fc = fa * fb
    c = ifft(fc)
    
    result = [0] * n
    carry = 0
    for i in range(n):
        result[i] = int(np.round(c[i].real)) + carry
        carry = result[i] // 10
        result[i] %= 10
    
    while len(result) > 1 and result[-1] == 0:
        result.pop()
    
    return ''.join(map(str, result[::-1]))
# 示例调用
print(multiply("123456789", "987654321"))  # 输出: "121932631112635269"

算法分析

  • 时间复杂度:(O(n log n)),其中 (n) 是结果数字的最大长度。这得益于FFT和逆FFT的效率,它们将多项式乘法的复杂度从 (O(n^2)) 降至 (O(n log n))。
  • 空间复杂度:(O(n)),主要用于存储数字数组及其变换结果。

优点

  • 极高效:对于大规模数字运算,FFT比传统算法和Karatsuba算法更高效。
  • 广泛应用:FFT在科学计算和工程领域中有广泛应用,特别是在信号处理方面。

缺点

  • 实现复杂度:FFT算法比起简单的乘法算法要复杂,需要处理复数运算和逆变换。
  • 依赖外部库:为了高效实现FFT,通常依赖于专门的数学库,如 numpy。

此FFT方法适用于需要快速处理非常大的数字乘法的场景,例如在数据加密、大数科学计算中非常有用。

结论

为了直观地比较解决LeetCode题目43 "字符串相乘"的三种方法,下面的表格将展示它们在不同技术维度的性能和特点,包括时间复杂度、空间复杂度以及各自的优势和劣势。

特征 方法一:模拟乘法手算 方法二:Karatsuba算法 方法三:FFT乘法
时间复杂度 O(M*N) O(N^1.585) O(N log N)
空间复杂度 O(M+N) O(N) O(N)
优势 - 直观且易于实现
- 不需要复杂的数学背景
- 快于传统方法
- 分治方法减少乘法次数
- 最快的方法,适用于非常大的数
- 有效利用FFT算法加速计算
劣势 - 时间复杂度高
- 对于非常大的数字效率低
- 实现相对复杂
- 对初学者不友好
- 实现复杂,需要数学背景知识
- 依赖外部数学库如numpy
适用场景 - 小到中等规模的数字
- 教学和简单应用
- 大数字乘法
- 需要快速算法但又不至于用FFT
- 大规模数字计算
- 科学计算和工程应用

综合分析

方法一(模拟乘法手算)

  • 这种方法非常直观,模拟了人们在纸上进行乘法运算的过程。
  • 它最适合于数字规模较小(例如数位不超过几百)的场景。
  • 对于大规模数字(如数千位或更多),计算效率会显著降低。

方法二(Karatsuba 算法)

  • Karatsuba 算法通过分治技术提高了乘法的效率,适合中到大规模的数字乘法。
  • 虽然它比模拟乘法快,但在极大规模数字乘法(例如数万位)场景下,仍可能不够高效。

方法三(FFT乘法)

  • FFT 乘法提供了最优的时间复杂度,特别适合于大规模数位的乘法问题,如在密码学或大规模科学计算中常见。
  • FFT 的主要缺点是实现复杂性高,需要较强的数学背景支持,并且在某些实现中需要依赖专业的数学库。

在实际选择算法时,应考虑具体的应用需求、数字的规模以及可用资源(如是否可以使用外部库)。对于日常应用和教学,模拟乘法或Karatsuba算法通常足够用;而在需要处理非常大规模数字的科学计算中,FFT 算法是最佳选择。


欢迎关注微信公众号 数据分析螺丝钉


相关文章
|
2月前
|
数据采集 机器学习/深度学习 算法
别急着上算法,咱先把数据整明白:大数据分析的5个基本步骤,你都搞对了吗?
别急着上算法,咱先把数据整明白:大数据分析的5个基本步骤,你都搞对了吗?
98 4
|
2月前
|
存储 监控 算法
员工行为监控软件中的 Go 语言哈希表算法:理论、实现与分析
当代企业管理体系中,员工行为监控软件已逐步成为维护企业信息安全、提升工作效能的关键工具。这类软件能够实时记录员工操作行为,为企业管理者提供数据驱动的决策依据。其核心支撑技术在于数据结构与算法的精妙运用。本文聚焦于 Go 语言中的哈希表算法,深入探究其在员工行为监控软件中的应用逻辑与实现机制。
83 14
|
2月前
|
Go 索引
【LeetCode 热题100】394:字符串解码(详细解析)(Go语言版)
本文详细解析了 LeetCode 热题 394:字符串解码。题目要求对编码字符串如 `k[encoded_string]` 进行解码,其中 `encoded_string` 需重复 `k` 次。文章提供了两种解法:使用栈模拟和递归 DFS,并附有 Go 语言实现代码。栈解法通过数字栈与字符串栈记录状态,适合迭代;递归解法则利用函数调用处理嵌套结构,代码更简洁。两者时间复杂度均为 O(n),但递归需注意栈深度问题。文章还总结了解题注意事项及适用场景,帮助读者更好地掌握字符串嵌套解析技巧。
71 6
|
3月前
|
自然语言处理 算法 安全
境内深度合成服务算法备案通过名单分析报告
本报告基于《境内深度合成服务算法备案通过名单》,分析了2023年6月至2025年3月公布的10批备案数据,涵盖属地分布、行业应用及产品形式等多个维度。报告显示,深度合成算法主要集中于经济发达地区,如北京、广东、上海等地,涉及教育、医疗、金融、娱乐等多行业。未来趋势显示技术将向多模态融合、行业定制化和安全合规方向发展。建议企业加强技术研发、拓展应用场景、关注政策动态,以在深度合成领域抢占先机。此分析旨在为企业提供参考,助力把握技术发展机遇。
境内深度合成服务算法备案通过名单分析报告
|
3月前
|
供应链 算法 搜索推荐
从公布的前十一批其他算法备案通过名单分析
2025年3月12日,国家网信办发布算法备案信息,深度合成算法通过395款,其他算法45款。前10次备案中,深度合成算法累计3234款,其他类别647款。个性化推送类占比49%,涵盖电商、资讯、视频推荐;检索过滤类占31.53%,用于搜索优化和内容安全;调度决策类占9.12%,集中在物流配送等;排序精选类占8.81%,生成合成类占1.55%。应用领域包括电商、社交媒体、物流、金融、医疗等,互联网科技企业主导,技术向垂直行业渗透,内容安全和多模态技术成新增长点。未来大模型检索和多模态生成或成重点。
从公布的前十一批其他算法备案通过名单分析
|
3月前
|
存储 机器学习/深度学习 缓存
🚀 力扣热题 394:字符串解码(详细解析)(Go语言版)
文章提供了两种解法:栈结构和递归解法。栈解法通过维护数字栈与字符串栈,依次处理 `[` 和 `]`,构造解码结果;递归解法则利用函数调用逐层解析嵌套结构。两者时间复杂度均为 $O(n)$,空间复杂度也为 $O(n)$。栈解法直观易懂,适合初学者;递归解法优雅简洁,适合处理深度嵌套规则。掌握这两种方法,可灵活应对类似问题,提升解题能力。
114 11
|
3月前
|
人工智能 自然语言处理 供应链
从第十批算法备案通过名单中分析算法的属地占比、行业及应用情况
2025年3月12日,国家网信办公布第十批深度合成算法通过名单,共395款。主要分布在广东、北京、上海、浙江等地,占比超80%,涵盖智能对话、图像生成、文本生成等多行业。典型应用包括医疗、教育、金融等领域,如觅健医疗内容生成算法、匠邦AI智能生成合成算法等。服务角色以面向用户为主,技术趋势为多模态融合与垂直领域专业化。
|
3月前
|
人工智能 自然语言处理 算法
从第九批深度合成备案通过公示名单分析算法备案属地、行业及应用领域占比
2024年12月20日,中央网信办公布第九批深度合成算法名单。分析显示,教育、智能对话、医疗健康和图像生成为核心应用领域。文本生成占比最高(57.56%),涵盖智能客服、法律咨询等;图像/视频生成次之(27.32%),应用于广告设计、影视制作等。北京、广东、浙江等地技术集中度高,多模态融合成未来重点。垂直行业如医疗、教育、金融加速引入AI,提升效率与用户体验。
|
17天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于PSO粒子群优化TCN-LSTM时间卷积神经网络时间序列预测算法matlab仿真
本内容展示了一种基于粒子群优化(PSO)与时间卷积神经网络(TCN)的时间序列预测方法。通过 MATLAB2022a 实现,完整程序运行无水印,核心代码附详细中文注释及操作视频。算法利用 PSO 优化 TCN 的超参数(如卷积核大小、层数等),提升非线性时间序列预测性能。TCN 结构包含因果卷积层与残差连接,结合 LSTM 构建混合模型,经多次迭代选择最优超参数,最终实现更准确可靠的预测效果,适用于金融、气象等领域。
|
14天前
|
算法 数据安全/隐私保护
基于Logistic-Map混沌序列的数字信息加解密算法matlab仿真,支持对文字,灰度图,彩色图,语音进行加解密
本项目实现了一种基于Logistic Map混沌序列的数字信息加解密算法,使用MATLAB2022A开发并包含GUI操作界面。支持对文字、灰度图像、彩色图像和语音信号进行加密与解密处理。核心程序通过调整Logistic Map的参数生成伪随机密钥序列,确保加密的安全性。混沌系统的不可预测性和对初值的敏感依赖性是该算法的核心优势。示例展示了彩色图像、灰度图像、语音信号及文字信息的加解密效果,运行结果清晰准确,且完整程序输出无水印。
基于Logistic-Map混沌序列的数字信息加解密算法matlab仿真,支持对文字,灰度图,彩色图,语音进行加解密

热门文章

最新文章

推荐镜像

更多