力扣第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 和最终的结果字符串。
相关推荐
布谷歌10 分钟前
Oops! 更改field的数据类型,影响到rabbitmq消费了...(有关于Java序列化)
java·开发语言·分布式·rabbitmq·java-rabbitmq
PXM的算法星球12 分钟前
java(spring boot)实现向deepseek/GPT等模型的api发送请求/多轮对话(附源码)
java·gpt·microsoft
被程序耽误的胡先生15 分钟前
java中 kafka简单应用
java·开发语言·kafka
F202269748627 分钟前
Spring MVC 对象转换器:初级开发者入门指南
java·spring·mvc
夏末秋也凉41 分钟前
力扣-回溯-491 非递减子序列
数据结构·算法·leetcode
penguin_bark42 分钟前
三、动规_子数组系列
算法·leetcode
楠枬1 小时前
网页五子棋——对战后端
java·开发语言·spring boot·websocket·spring
kyle~1 小时前
thread---基本使用和常见错误
开发语言·c++·算法
YXWik61 小时前
23种设计模式
java·设计模式