第一道中等难度的题,这题主要是熟悉链表结构
回顾一下这道题的思路:
题目要求是将两个非空链表所代表的数字加起来返回结果的头链表,数字倒序存储在链表中,均为非负数。
那么很明显要注意为0的情况。既然是逆序排列就符合加法的逻辑顺序,我们设定一个进位位carry辅助加法。
int carry = 0;
开始carry为0,每一次相加时我们都要加上carry的值,每一次加完后我们都要判断下一位是否需要进位,可以用>10判断,题目中用了
int sum = x + y + carry;
carry = sum/10;
x,y是当前两个链表相加的数字。
那么对于两个数字位数不相同的情况,我们要做一些限制。只要有一个数字还没有循环完我们就要继续相加,所以循环判断条件使用了
while(p1!=null || p2!= null)
另外已经结束循环的链表仍然在相加,我们要更新此时被加的值为0,由于数据结构是链表,所以我们让它的ListNode不改变,停留在当前链表处,否则会报错。
在这个过程中还要保存每一位加法结果并更新答案链表,我们使用了
ListNode cur = new ListNode(0);
ListNode head = cur;
cur用于链接答案链表,在每次加法之后我们得到相加结果:
int sum = x + y + carry;
cur.next = new ListNode(sum%10);
并更新cur:
cur = cur.next;
最关键的exception是当n位数字和m位数字相加后,在最高位出现了x+y+carry >10,这样就会得到长度为max(n,m)+1位的链表,对于这种情况,我们在循环结束后直接检查carry是否为1(或是否>0),如果是的话我们追加
cur.next = new ListNode(1);
最终返回head.next,head是哑节点。
post一下代码:
public static ListNode addTwoNumbers(ListNode l1, ListNode l2){
ListNode head = new ListNode(0);
ListNode cur = head;
int carry = 0;
ListNode p = l1;
ListNode q = l2;
while(p!=null || q!=null){
int x = p==null ? 0 : p.val;
int y = q==null ? 0 : q.val;
int sum = x+y+carry;
carry = sum/10;
ListNode nextnode = new ListNode(sum%10);
cur.next=nextnode;
cur = cur.next;
if(p!=null) p = p.next;
if(q!=null) q = q.next;
}
if(carry>0){
cur.next = new ListNode(1);;
}
return head.next;
}