题目描述:
怎么思考?(重点)数字基于示例
大体思路,题目以及给了两个链表,所以一位一位来看,比如第一位就是2+5=7,这个7一定也是一个链表元素及节点。第二位4+6=10,只去个位,并且要记录十位的进位(涉及基本算法),因为进位会影响到下一位的值。最后一位就是前一位的进位+两个节点的值。具体如何实现?
- 需要记下每次的进位值carry(初始为0),并且下次计算加上前carry
- 创建一个函数appendNode,把计算完的节点放入
- 两个链表对应节点分别都往后移,next到下一个节点,重复上步步骤
- 别忘记考虑当两个链表位数不齐时如何处理。例:第一条链表元素为9→9→9→9,第二条链表元素为9,那么两条链表元素不断相加移位时,第二条链表在第二个节点会到达null值,无法与链表一正常计算
我们先看一下预备知识:
1、a为一个两位整数,如何计算a的个位数和十位数?
a % 10 //求余计算出个位
a / 10 //除数计算十位
及对应题中,只求4+6=10的个位(%10)和进位值carry(/10)
2、链表需要新建一个固定头指针DummyHead,当需要next移动指针时,需要另一个指针tail指向DummyHead,替它(大概是替这个意思?)完成next功能:把相加好的元素作为新节点(即appendNode函数的输入),使tail的下一个(next)指向这个新节点,并让tail就变成这个新节点(注意是先指再赋值)这样方便下一个节点的计算
void appendNode(ListNode node){
tail.next=node;
tail=node;
}
3、上述说到当两条链表不一样长(也就是元素个数不一样),无法进行相加,要对l1和l2进行长度判断
while(l1!=null && l2!=null){
}
while(l1!=null && l2==null){
}
while(l2!=null && l1==null){
}
if(carry!=0){
} //这个if单独列出来是判断当两个链表元素都到末尾时,还有进位值时需要单独考虑
4、需要注意题目在输入已给ListNode的建立
/**
* 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; }
* }
*/
即我们可以直接使用l1.val、l2.val和l1.next、l2.next
其实即使看完这些离散的东西,可能还无法想到具体的伪代码,所以还是先看答案
全代码:
/**
* 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 {
ListNode DummyHead=new ListNode(-1);
ListNode tail=DummyHead;
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int carry=0;
while(l1!=null && l2!=null){
int val=(l1.val+l2.val+carry)%10;
carry=(l1.val+l2.val+carry)/10;
appendNode(new ListNode(val));
l1=l1.next;
l2=l2.next;
}
while(l1!=null && l2==null){
int val=(l1.val+carry)%10;
carry=(l1.val+carry)/10;
appendNode(new ListNode(val));
l1=l1.next;
}
while(l2!=null && l1==null){
int val=(l2.val+carry)%10;
carry=(l2.val+carry)/10;
appendNode(new ListNode(val));
l2=l2.next;
}
if(carry!=0){
int val=carry;
appendNode(new ListNode(val));
}
return DummyHead.next;
}
void appendNode(ListNode node){
tail.next=node;
tail=node;
}
}
可以和我刚刚总结的知识结合起来细品一下,注意每个函数返回的类型,其中需注意要返回return DummyHead.next(DummyHead是tail的指向,且初始赋为-1,需要next下一个元素)