1 题目
leetCode
虽然题目说了一大堆,但事实上执行的就是对链表上的数从左到右逐位相加,一开始理解错题意还以为要将链表反转之后再次相加,看了题解才发现是我想多了。
2 解
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head=null;
ListNode cur=null;
int carry=0;
int sum=0;
while(l1!=null || l2!=null){
//如果l1不为空则取他的值,为空则补零,l2同理
int a= l1!=null?l1.val : 0;
int b= l2!=null?l2.val : 0;
sum= a+b+carry;
carry= sum>=10 ? 1 : 0;
sum=sum%10;
if(head == null){
cur = new ListNode(sum);
head=cur;
}else{
cur.next = new ListNode(sum);
cur=cur.next;
}
if(l1!=null)
l1=l1.next;
if(l2!=null)
l2=l2.next;
}
//为什么直接写 cur而不用判断是不是head?因为只有之前有数相加才会有进位,
//所以直接改cur就可以了,head必不为空
if(carry==1)
cur.next=new ListNode(1);
return head;
}
3 收获
3.1 错误的链表连接
一开始我的结果链表是这样子的,看起来也挺有道理,无head则创建head,把head指向cur,有head则创建cur并移动cur,但是这样子是错误的,为什么呢?因为 cur一开始指向空,相当于将head的next指向空,而cur在创建的时候直接指向了新的ListNode,这代码执行到最后就是内存中一堆节点,但是全都没有连接起来。
if(head == null){
head=new ListNode(sum);
head.next=cur;
}else{
cur=new ListNode(sum);
cur=cur.next;
}
3.2 反转链表
前面提到了反转,这里就记录一下如何反转单链表吧,当链表为空时返回空,只有一个节点时返回自身,单链表的逆序需要维护三个指针,指向当前节点的cur,指向前一节点的pre,指向下一节点的next,每次都是将cur的next指向pre,然后pre指向cur,cur指向next,next指向next.next,当next为空时说明到达了链表结尾,此时将cur的next指向pre,就完成整个链表的逆序。
反转链表在牛客上的链接
public ListNode ReverseList(ListNode head) {
if(head==null)
return null;
if(head.next==null) {
return head;
}
//上面两个if可以合并 if(head == null || head.next == null) return head;
ListNode pre=null;
ListNode cur=head;
ListNode next=head.next;
while(next!=null) {
cur.next=pre;
pre=cur;
cur=next;
next=next.next;
}
cur.next=pre;
return cur;
}
九月中旬终于开始投递,九月末做了一些笔试,觉得自己的算法还需加强,国庆学习了左神算法,台式没带回去所以笔记在本子上,国庆回来被笔试打自闭了几天,但是一直自闭也不是个事,都不容易,坚持就是胜利。