Leetcode - Multiply String

本文深入分析了两种大数乘法算法:方法1采用传统笔算乘法,方法2则通过逐位相乘优化效率。通过比较两者的时间复杂度和操作数量,揭示方法2在处理任意大小的非负整数乘法时的优势。
Given two numbers represented as strings, return multiplication of the numbers as a string.

Note: The numbers can be arbitrarily large and are non-negative.

[分析] Naive的做法是模拟笔算乘法操作,从高位到低位的顺序将num2 上的每一位同num1 相乘,由于运算顺序从高到低,每次运算时将上一次运算结果后加0,(相当于*10)后同本次乘积结果加和。 高效做法(Method 2)思路:num1 * num2, num2上的每一位依次和num1中的每一位相乘,num2的个位同num1的个位相乘结果包含在最终乘积的个位上,同理num2的个位同num1的十位相乘结果包含在最终乘积的十位上,num2的十位同num1的个位相乘结果也包含在最终乘积的十位上,一般的,num2的第 i 位 同num1的第 j 位相乘结果包含在最终乘积的第 i + j 位,遍历两个数的每一位,可以得到最终乘积各位上的结果。这样得到的乘积各位上可能是两位数,因此还需要处理使得乘积结果各位上为单个数字,处理方式就是依次进位。Method 1有O(m * n)次 *、\、% 以及字符串append操作, O(m * (m + n))次 +, append操作,而Method 2仅有O(m * n)次 *、+ 以及O(m + n)次 \、%、append操作,我们知道除法和取模是最耗时的,所以前者超时也就不难怪了。


// method 2:
public String multiply(String num1, String num2) {
if (num1 == null || num2 == null || num1.length() == 0 || num2.length() == 0)
return null;
if (num1.length() < num2.length())
return multiply(num2, num1);
if (num2.equals("0")) return "0";
if (num2.equals("1")) return num1;
int[] result = new int[num1.length() + num2.length() - 1];
for (int i = num2.length() - 1; i >= 0; i--) {
int digit1 = num2.charAt(i) - '0';
for (int j = num1.length() - 1; j >= 0; j--) {
result[i + j] += digit1 * (num1.charAt(j) - '0');
}
}
int carry = 0;
for (int i = result.length - 1; i >= 0; i--) {
result[i] += carry;
carry = result[i] / 10;
result[i] %= 10;
}
StringBuilder val = new StringBuilder();
if (carry > 0)
val.append(carry);
for (int i = 0; i < result.length; i++)
val.append(result[i]);
return val.toString();
}
// method 1 :
public String multiply1(String num1, String num2) {
if (num1 == null || num2 == null || num1.length() == 0 || num2.length() == 0)
return null;
String result = "";
for (int i = 0; i < num2.length(); i++) {
result = add(result + '0', multiOneDigit(num1, num2.charAt(i) - '0'));
}
return result;
}
private String add(String num1, String num2) {
if (num1.length() < num2.length()) {
String tmp = num2;
num2 = num1;
num1 = tmp;
}
StringBuilder sum = new StringBuilder();
int carry = 0, val = 0;
int i = num1.length() - 1, j = num2.length() - 1;
while (j >= 0) {
val = (num1.charAt(i) - '0') + (num2.charAt(j) - '0');
sum.append(val - 10); // val % 10
carry = val >= 10 ? 1 : 0; // val / 10
i--; j--;
}
while (i >= 0) {
val = (num1.charAt(i--) - '0') + carry;
sum.append(val - 10);
carry = val >= 10 ? 1 : 0;
}
if (carry > 0) sum.append(carry);
return sum.reverse().toString();
}
private String multiOneDigit(String num1, int num2) {
StringBuilder result = new StringBuilder();
int carry = 0, val = 0;
for (int i = num1.length() - 1; i >= 0; i--) {
val = (num1.charAt(i) - '0') * num2 + carry;
result.append(val % 10);
carry = val / 10;
}
if (carry > 0)
result.append(carry);
return result.reverse().toString();
}
乐播投屏是一款简单好用、功能强大的专业投屏软件,支持手机投屏电视、手机投电脑、电脑投电视等多种投屏方式。 多端兼容与跨网投屏:支持手机、平板、电脑等多种设备之间的自由组合投屏,且无需连接 WiFi,通过跨屏技术打破网络限制,扫一扫即可投屏。 广泛的应用支持:支持 10000+APP 投屏,包括综合视频、网盘与浏览器、美韩剧、斗鱼、虎牙等直播平台,还能将央视、湖南卫视等各大卫视的直播内容一键投屏。 高清流畅投屏体验:腾讯独家智能音画调校技术,支持 4K 高清画质、240Hz 超高帧率,低延迟不卡顿,能为用户提供更高清、流畅的视觉享受。 会议办公功能强大:拥有全球唯一的 “超级投屏空间”,扫码即投,无需安装。支持多人共享投屏、远程协作批注,PPT、Excel、视频等文件都能流畅展示,还具备企业级安全加密,保障会议资料不泄露。 多人互动功能:支持多人投屏,邀请好友加入投屏互动,远程也可加入。同时具备一屏多显、语音互动功能,支持多人连麦,实时语音交流。 文件支持全面:支持 PPT、PDF、Word、Excel 等办公文件,以及视频、图片等多种类型文件的投屏,还支持网盘直投,无需下载和转格式。 特色功能丰富:投屏时可同步录制投屏画面,部分版本还支持通过触控屏或电视端外接鼠标反控电脑,以及在投屏过程中用画笔实时标注等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值