LeetCode 两数相加
题目1
题目描述
给定两个字符串形式的**非负整数** num1 和num2 ,计算它们的和并同样以字符串形式返回。链接
你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。
分析
由于题目有一下要求:
- 不能使用任何库函数
- 不能直接将输入的字符串转换为整数形式
并且如果直接使用数字相加可能出现越界问题,所以我们这里采用最基础的加法思路,即将两个数的对应位依次相加,如下所示,我们需要计算123+48
-
首先,我们需要将两个数的最低位即个位相加,temp=3+8=11,由于11超过10,需要进位11/10=1,本位**保留** 11%10= 1
-
接着计算十位,2+4 +1(进位的1)=7
-
最后计算1**+0(由于没有进位,本位也没有,所以相当于加0)**=1
-
最终结果即为171
综上:需要解决以下问题
- 计算进位:carry = temp / 10
- 计算结果本位:(n+m+carry)%10
- 数字索引越界:i >= 0 ? num1.charAt(i) - ‘0’ : 0
- 循环结束后存在进位: res.append(carry)
解决
public String addStrings(String num1, String num2)
{
StringBuilder res = new StringBuilder();//记录最终结果
//记录两个数字的长度
int i = num1.length() - 1;
int j = num2.length() - 1;
//记录进位,初始位为0
int carry = 0;
//只要一个数字的还没加完,就继续循环
while (i >= 0 || j >= 0)
{
//从最低位起,将其逐字符转为数字相加
//如果当前位存在,将其转为数字
//如果当前位已经不存在,则用0替代
int n = i >= 0 ? num1.charAt(i) - '0' : 0;
int m = j >= 0 ? num2.charAt(j) - '0' : 0;
//记录当前位相加结果(两个相加后再加进位的carry)
int temp = n + m + carry;
//更新进位
carry = temp / 10;
//拼接当前位结果,只保留个位
res.append(temp % 10);
//指针左移
i--;
j--;
}
//如果循环结束后,标志位不为0,说明还有进位,则需要继续拼接进位
if (carry != 0)
{
res.append(carry);
}
//由于是从最低位相加,所以最终拼接后的字符串为结果的逆序,因此需要逆置
return res.reverse().toString();
}
题目2
题目描述
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。在线OJ
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
题目分析
题目1和题目2几乎相同,只是将字符串变为链表,因此我们只需要更改部分条件即可
- 由于返回结果为链表,所以定义两个指针,分别保存结果的头和尾
- 计算结果之前需要拼接字符串并反转,这里只需要添加到结果链表
- 指针后移时需要判断下一个节点是否为空,如果为空则不需要后移
解决
public ListNode addTwoNumbers(ListNode l1, ListNode l2)
{
//进位记录,初始化为0
int carry = 0;
//定义保存结果链表的头节点和尾结点
ListNode head = null;
ListNode tail = null;
//当有一个链表不为空,继续循环
while (l1 != null || l2 != null)
{
//记录当前节点大小,即对应位大小
//如果为为空,给0,如果不为空,保存当前节点
int n = l1 == null ? 0 : l1.val;
int m = l2 == null ? 0 : l2.val;
//计算结果
int temp = n + m + carry;
//计算进位
carry = temp / 10;
//计算本位
ListNode listNode = new ListNode(temp % 10);
//拼接结果链表
if (head == null)//如果头为空,将头节点和尾结点都指向该节点
{
head = listNode;
tail = listNode;
}
else//如果头不为空,拼接链表后将尾结点指向该节点
{
tail.next = listNode;
tail = tail.next;
}
//指针后移
if (l1 != null)
{
l1 = l1.next;
}
if (l2 != null)
{
l2 = l2.next;
}
}
//防止循环结束后还存在进位
if (carry != 0)
{
tail.next = new ListNode(carry);
}
//返回头节点
return head;
}