力扣第43题“字符串相乘”

力扣第43题"字符串相乘"

题目要求

给定两个表示非负整数的字符串 num1num2,计算它们的乘积并以字符串形式返回。

示例:

plaintext 复制代码
输入: num1 = "123", num2 = "456"
输出: "56088"

解题思路

  1. 模拟手算乘法:我们将每一位相乘,然后把结果存入一个数组中,最后转换成字符串。
  2. 进位处理:将数组中各个位置的数值按照进位规则进行调整。
  3. 跳过前导零:结果中可能会出现前导零,需要跳过这些零并将剩下的部分转换成字符串。

代码实现

以下是详细的代码实现和逐行解释:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 字符串相乘函数
char* multiply(char* num1, char* num2) {
    int len1 = strlen(num1);
    int len2 = strlen(num2);
    int totalLen = len1 + len2;
    
    // 创建数组来存储乘积的各个位的数值
    int* result = (int*)calloc(totalLen, sizeof(int));
    
    // 从个位开始逐位相乘
    for (int i = len1 - 1; i >= 0; i--) {
        for (int j = len2 - 1; j >= 0; j--) {
            int mul = (num1[i] - '0') * (num2[j] - '0');
            int p1 = i + j;
            int p2 = i + j + 1;
            
            // 叠加到当前位置的值,并处理进位
            int sum = mul + result[p2];
            result[p2] = sum % 10;
            result[p1] += sum / 10;
        }
    }
    
    // 跳过前导零
    int start = 0;
    while (start < totalLen && result[start] == 0) {
        start++;
    }
    
    // 若结果为零,则直接返回 "0"
    if (start == totalLen) {
        free(result);
        return strdup("0");
    }
    
    // 转换结果为字符串
    char* product = (char*)malloc((totalLen - start + 1) * sizeof(char));
    for (int i = start; i < totalLen; i++) {
        product[i - start] = result[i] + '0';
    }
    product[totalLen - start] = '\0';
    
    free(result);
    return product;
}

// 测试代码
int main() {
    char num1[] = "123";
    char num2[] = "456";
    
    char* result = multiply(num1, num2);
    printf("结果: %s\n", result);
    
    free(result);
    return 0;
}

代码解析

  1. 数组存储结果

    c 复制代码
    int* result = (int*)calloc(totalLen, sizeof(int));

    创建一个大小为 len1 + len2 的数组 result,用于存储相乘结果的每个位的数值。

  2. 逐位相乘并叠加

    c 复制代码
    for (int i = len1 - 1; i >= 0; i--) {
        for (int j = len2 - 1; j >= 0; j--) {
            int mul = (num1[i] - '0') * (num2[j] - '0');
            int p1 = i + j;
            int p2 = i + j + 1;
            
            int sum = mul + result[p2];
            result[p2] = sum % 10;
            result[p1] += sum / 10;
        }
    }
    • 外层循环遍历 num1 的每一位,内层循环遍历 num2 的每一位。
    • 计算 num1[i]num2[j] 的乘积,将结果添加到 result 数组的对应位置,处理进位。
  3. 跳过前导零

    c 复制代码
    int start = 0;
    while (start < totalLen && result[start] == 0) {
        start++;
    }

    计算后的 result 数组中可能包含前导零,找到第一个非零位置。

  4. 转换结果为字符串

    c 复制代码
    char* product = (char*)malloc((totalLen - start + 1) * sizeof(char));
    for (int i = start; i < totalLen; i++) {
        product[i - start] = result[i] + '0';
    }
    product[totalLen - start] = '\0';
    • 分配 product 字符串并将 result 数组中非零部分的每一位转为字符,最后在末尾加上字符串结束符 \0
  5. 特殊情况检查

    如果结果中全为零,直接返回字符串 "0"

复杂度分析

  • 时间复杂度O(n * m),其中 nm 分别为 num1num2 的长度。
  • 空间复杂度O(n + m),用于存储结果的数组 result 和最终的结果字符串。
相关推荐
Knight_AL13 小时前
Java 多态详解:概念、实现机制与实践应用
java·开发语言
C雨后彩虹13 小时前
volatile 实战应用篇 —— 典型场景
java·多线程·并发·volatile
xie_pin_an13 小时前
从二叉搜索树到哈希表:四种常用数据结构的原理与实现
java·数据结构
没有bug.的程序员13 小时前
Java 并发容器深度剖析:ConcurrentHashMap 源码解析与性能优化
java·开发语言·性能优化·并发·源码解析·并发容器
不知名XL13 小时前
day27 贪心算法 part05
算法·贪心算法
Tisfy13 小时前
LeetCode 3047.求交集区域内的最大正方形面积:2层循环暴力枚举
算法·leetcode·题解·模拟·枚举·几何
junziruruo14 小时前
t-SNE可视化降维技术(以FMTrack频率感知与多专家融合文章中的内容为例)
人工智能·算法
藦卡机器人14 小时前
自动焊接机器人的核心技术要求与标准
人工智能·算法·机器人
kk哥889914 小时前
分享一些学习JavaSE的经验和技巧
java·开发语言
2501_9403152614 小时前
【无标题】1.17给定一个数将其转换为任意一个进制数(用栈的方法)
开发语言·c++·算法