一、题目
牛客题目链接:大数加法_牛客题霸_牛客网
LeeCode 题目链接:
题目描述:
以字符串的形式读入两个数字,编写一个函数计算它们的和,以字符串形式返回。
数据范围:s.length,t.length≤100000,字符串仅由'0'~‘9’构成
要求:时间复杂度 O(n)
示例1
输入:"1","99"
返回值:"100"
说明:1+99=100
示例2
输入:"114514",""
返回值:"114514"
二、解题思路&&代码实现:
方案一:模拟法
实现思路:
- 从后往前遍历两个字符串
- 逐位相加,考虑进位
- 构建结果字符串
复杂度分析:
时间复杂度O(max(lens, lent)):lens = s.length(), lent = t.length(),取决于长度较长的字符串
空间复杂度O(1):常数级空间存储
java:
public class Solution {
public String addStrings(String s, String t) {
StringBuilder res = new StringBuilder();
int i = s.length() - 1;
int j = t.length() - 1;
int carry = 0;
while (i >= 0 || j >= 0 || carry > 0) {
int a = i >= 0 ? s.charAt(i--) - '0' : 0;
int b = j >= 0 ? t.charAt(j--) - '0' : 0;
int sum = a + b + carry;
res.append(sum % 10);
carry = sum / 10;
}
return res.reverse().toString();
}
}
java 的第二种实现:
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算两个数之和
* @param s string字符串 表示第一个整数
* @param t string字符串 表示第二个整数
* @return string字符串
*/
public String solve (String s, String t) {
// 表示字符串的字符位置,需要从低位开始计算
int s1 = s.length() - 1;
int t1 = t.length() - 1;
// 表示进位
int carry = 0;
StringBuilder sb = new StringBuilder();
while (s1 >= 0 || t1 >= 0 || carry > 0) {
int n1 = s1 < 0 ? 0 : (s.charAt(s1--) - '0');
int n2 = t1 < 0 ? 0 : (t.charAt(t1--) - '0');
// 计算和
int sum = n1 + n2 + carry;
// 计算进位
carry = sum / 10;
sum = sum % 10;
// 从头部插入,保证结果的顺序
sb.insert(0, sum);
}
return sb.toString();
}
}
php :
function addStrings(string $s, string $t): string {
$res = [];
$i = strlen($s) - 1;
$j = strlen($t) - 1;
$carry = 0;
while ($i >= 0 || $j >= 0 || $carry > 0) {
$a = $i >= 0 ? intval($s[$i--]) : 0;
$b = $j >= 0 ? intval($t[$j--]) : 0;
$sum = $a + $b + $carry;
array_push($res, $sum % 10);
$carry = intdiv($sum, 10);
}
return implode('', array_reverse($res));
}
golang:
func addStrings(s string, t string) string {
var res []byte
i, j := len(s)-1, len(t)-1
carry := 0
for i >= 0 || j >= 0 || carry > 0 {
a := 0
if i >= 0 {
a = int(s[i] - '0')
i--
}
b := 0
if j >= 0 {
b = int(t[j] - '0')
j--
}
sum := a + b + carry
res = append(res, byte(sum%10)+'0')
carry = sum / 10
}
// 反转结果
for left, right := 0, len(res)-1; left < right; left, right = left+1, right-1 {
res[left], res[right] = res[right], res[left]
}
return string(res)
}
python:
def add_strings(s: str, t: str) -> str:
res = []
i, j = len(s) - 1, len(t) - 1
carry = 0
while i >= 0 or j >= 0 or carry > 0:
a = int(s[i]) if i >= 0 else 0
b = int(t[j]) if j >= 0 else 0
total = a + b + carry
res.append(str(total % 10))
carry = total // 10
i -= 1
j -= 1
return ''.join(reversed(res))
方案二:
实现思路:
- 数字相加部分同上;
- 只是在将每一位的相加结果入栈存储,当循环完之后再将栈中数据依次出栈形成字符串
java:
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算两个数之和
* @param s string字符串 表示第一个整数
* @param t string字符串 表示第二个整数
* @return string字符串
*/
public String solve (String s, String t) {
// write code here
Stack<Integer> stack = new Stack<>();
StringBuilder stringBuilder = new StringBuilder();
int i = s.length() - 1, j = t.length() - 1, carry = 0;
while (i >= 0 || j >= 0 || carry != 0) {
carry += i >= 0 ? s.charAt(i--) - '0' : 0;
carry += j >= 0 ? t.charAt(j--) - '0' : 0;
stack.push(carry % 10);
carry = carry / 10;
}
while (!stack.isEmpty())
stringBuilder.append(stack.pop());
return stringBuilder.toString();
}
}
方案三:利用语言特性直接实现
python 直接实现
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 计算两个数之和
# @param s string字符串 表示第一个整数
# @param t string字符串 表示第二个整数
# @return string字符串
#
class Solution:
def solve(self , s: str, t: str) -> str:
# write code here
return int(s)+int(t);
java :(java中的大数操作BigInteger,直接进行大数之间的运算,可以直接得到最终的结果。)
import java.util.*;
import java.math.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算两个数之和
* @param s string字符串 表示第一个整数
* @param t string字符串 表示第二个整数
* @return string字符串
*/
public String solve (String s, String t) {
BigInteger biginteger1 = new BigInteger(s);
BigInteger biginteger2 = new BigInteger(t);
return biginteger1.add(biginteger2).toString();
}
}