题目描述:
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
思想:
由于链表的开头就是最低位,所以直接从前往后遍历两个链表,两两相加,结果保存到一个新的节点中。遍历过程中,遇到空节点,设置值为0,如果相加的和大于10,那么进位标志carry=1,同时结果sum%10保存到新节点中, 循环退出之后,最高位的进位问题,如果carry=1,则还需要新建一个值为1的节点。
PS:看到链表就想指针,另外多考虑边界条件,对于特出情况作出处理
// 定义链表节点。通过调用next,多个节点形成了链表
class ListNode
{
int val;
ListNode next;
// 构造方法,创建类自动运行
public ListNode(int x){
val=x;
}
}
public class test {
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
// 新建一个链表节点,只包含一个0,节点
ListNode dummy = new ListNode(0);
// 新建指针cur,指向链表。。其实cur也是一个链表节点
ListNode cur = dummy;
// 定义进位标志
int carry = 0;
// 两个节点至少一个为非空,才能相加
while (l1 != null || l2 != null) {
// 如果为空,则定义为0,非空,则取值val
int d1 = l1 == null ? 0 : l1.val;
int d2 = l2 == null ? 0 : l2.val;
// 节点相加
int sum = d1 + d2 + carry;
// 如果相加和大于10,更改进位标志位1
carry = sum >= 10 ? 1 : 0;
// 创建新的节点,存储相加的和(取余)
cur.next = new ListNode(sum % 10);
// 移动指针,指向当前节点
cur = cur.next;
// l1与l2后移一位
if (l1 != null) l1 = l1.next;
if (l2 != null) l2 = l2.next;
}
// 如果进位标志为1,表示最高位相加之后,继续进位,那么新建一个节点1,放到最后
if (carry == 1) cur.next = new ListNode(1);
// 跳过第一个节点,返回的依然是一个节点ListNode
return dummy.next;
}
// 编写初始化链表的函数
public static void add(ListNode node, int [] data) {
ListNode temp = node;
if (data.length == 0) {
return;
}
for (int i = 0; i < data.length; i++) {
temp.next = new ListNode(data[i]);
temp = temp.next;
}
}
// 编写打印链表的函数
public static void LinkedPrint(ListNode node) {
if(node == null) {
return;
}
while (node != null) {
System.out.print(node.val + " ");
node = node.next;
}
}
public static void main(String[] args) {
// 初始化为0,这样相加不影响
ListNode l1 = new ListNode(0);
int [] num1 = {2, 4, 3};
add(l1, num1);
ListNode l2 = new ListNode(0);
int [] num2 = {5, 6, 4};
add(l2, num2);
ListNode result = addTwoNumbers(l1.next, l2.next);
LinkedPrint(result);
}
}