两数相加
题目描述
难度:中等。
解决方法
方法一:模拟。
最简单想到的方法是模拟,从头到尾遍历两个链表,模拟逐位相加并处理进位。
首先,定义了两个指针head 和 tail,用于构建结果链表。定义整型变量 car,用于保存进位。
使用 while 循环遍历输入的两个链表 l1 和 l2,同时计算它们对应节点的和,以及考虑进位。在每次循环中,计算当前节点的和 sum。使用条件语句检查 head 是否为 null。如果 head 为 null,表示结果链表还没有创建,因此需要创建一个新的节点,并将 head 和 tail 都指向这个新节点。如果 head 不为 null,则创建一个新的节点 node,并将其添加到结果链表的末尾,然后将 tail 移动到新的节点上,并更新进位值 car。移动 l1 和 l2 的指针到下一个节点,继续下一轮循环,直到两个链表都遍历完。
如果其中一个链表 l1 或 l2 还有剩余节点,继续循环处理,加上进位并构建结果链表。
最后,如果循环结束后仍然存在进位 car,需要创建一个新的节点,将其添加到结果链表的末尾,以处理最高位的进位。
返回结果链表 head,它包含了两个输入链表相加的结果。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = null,tail = null;
int car = 0; \\保存进位
while(l1!=null&&l2!=null){ \\l1和l2都不为空的情况
int sum = l1.val + l2.val + car;
if(head == null){ \\当前头指针为空
head = tail = new ListNode(sum % 10);
}else{
ListNode node = new ListNode(sum % 10);
tail.next = node;
tail = tail.next;
}
car = sum / 10;
l1 = l1.next;
l2 = l2.next;
}
while(l1!=null){ \\l2为空的情况
int sum = l1.val + car;
if(head == null){
head = tail = new ListNode(sum % 10);
}else{
ListNode node = new ListNode(sum % 10);
tail.next = node;
tail = tail.next;
}
car = sum / 10;
l1 = l1.next;
}
while(l2!=null){ \\l1为空的情况
int sum = l2.val + car;
if(head == null){
head = tail = new ListNode(sum % 10);
}else{
ListNode node = new ListNode(sum % 10);
tail.next = node;
tail = tail.next;
}
car = sum / 10;
l2 = l2.next;
}
if(car > 0){ \\当l1和l2都为空时,一定要检查当前进位是否为0
ListNode node = new ListNode(car);
tail.next = node;
}
return head;
}
}
方法二:递归。
将两个逆序存储的非负整数链表相加,并返回结果链表。这个题目可以使用递归的方式来实现
实现addTwoNumbers 方法,它接受两个输入链表 l1 和 l2,并返回一个新的链表,表示它们的和。该方法内部调用了 add 方法,同时传递了一个初始的进位值 0。
add 方法是递归方法,用于处理两个链表的当前节点相加以及考虑进位的情况。如果 l1 和 l2 都为 null,表示两个链表都已经遍历完,如果当前仍然存在进位 car(值为1),则创建一个新的节点表示进位,否则返回 null。计算当前节点的和 sum,等于进位 car 加上 l1 节点的值(如果不为 null),再加上 l2 节点的值(如果不为 null)。创建一个新的节点 l3,其值为 sum 的个位数,即 sum % 10。递归调用 add 方法,传递下一个节点 l1.next、l2.next,以及新的进位值 sum / 10。将递归返回的结果链表设置为 l3 的下一个节点。返回 l3,即当前节点的结果。
递归过程会持续执行,直到两个链表都遍历完,或者最高位的进位也被处理完毕。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2){
return add(l1, l2, 0);
}
public ListNode add(ListNode l1, ListNode l2, int car) {
if(l1==null && l2==null){
return car==1?new ListNode(car):null;
}
int sum = car + (l1==null?0:l1.val) + (l2==null?0:l2.val);
ListNode l3 = new ListNode(sum%10);
l3.next = add((l1==null?null:l1.next), (l2==null?null:l2.next), sum/10);
return l3;
}
}
加油!