两数相加
解法一
正确的解法:
//错误点三:
//指向空指针null的结点不可以指向新的结点
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
/** 题目重点:
1.两个 非空 的链表(表示两个非负的整数);
2.每位数字都是按照 逆序 的方式存储的
3.每个节点只能存储 一位 数字。
4.将两个数相加,并以相同形式返回一个表示和的链表
5.你可以假设除了数字 0 之外,这两个数都不会以 0 开头。(除了0以为不用考虑以0开头的数字)
*/
//题目已经告知:用链表
//考察内容:两链表的求和
//l1来记录最终的结果
ListNode p1=l1,p2=l2;
// 进位
int so=0;
if(p1!=null&&p2!=null){
// 求两个元素之和
int val=p1.val+p2.val+so;
// 本位
p1.val=val%10;
// 进位
so=val/10;
}
// 结束条件:两链表中其中一个链表遍历完
while(p1.next!=null&&p2.next!=null){
// 求两个元素之和
int val=p1.next.val+p2.next.val+so;
// 本位
p1.next.val=val%10;
// 进位
so=val/10;
p1=p1.next;
p2=p2.next;
}
// 错误一:考虑不全面,未考虑到进位不为零
// if(p2!=null){
// p1=p2;
// }考虑不全
// 错误二:没考虑遍历完后进位为1,会创建一个新的节点,val为1
// // 进位为0的时候
// // p2不为空,则要将l1的末尾指向p2
// if(so==0&&p2!=null){
// p1=p2;
// }
// // 有进位
// else if(so!=0){
// // 当p1不为空时
// if(p1!=null){
// 结束条件:p1遍历完或者进位为零
// while(p1!=null&&so!=0){
// 求和
// int val=p1.val+so;
// 本位
// p1.val=val%10;
// 进位
// so=val/10;
// p1=p1.next;
// }
// }
// 当p2不为空时
// else if(p2!=null){
// p1=p2;
// 结束条件:p1遍历完或者进位为零
// while(p2!=null&&so!=0){
// 求和
// int val=p2.val+so;
// 本位
// p2.val=val%10;
// 进位
// so=val/10;
// p2=p2.next;
// }
// }
// }
// 进位为0的时候
// p2不为空,则要将l1的末尾指向p2
if(so==0&&p2.next!=null){
p1.next=p2.next;
}
// 有进位
else if(so!=0){
// 当p1不为空时
if(p1.next!=null){
// 结束条件:p1遍历完或者进位为零
while(p1.next!=null&&so!=0){
// 求和
int val=p1.next.val+so;
// 本位
p1.next.val=val%10;
// 进位
so=val/10;
p1=p1.next;
}
}
// 当p2不为空时
else if(p2.next!=null){
p1.next=p2.next;
// 结束条件:p1遍历完或者进位为零
while(p2.next!=null&&so!=0){
// 求和
int val=p2.next.val+so;
// 本位
p2.next.val=val%10;
// 进位
so=val/10;
p2=p2.next;
}
}
}
// 相加之后产生的新的结点
if(so!=0){
while(p1.next!=null){
p1=p1.next;
}
ListNode p=new ListNode(so);
p1.next=p;
p.next=null;
}
return l1;
}
}
解法二
错误的答案:
class Solution{
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
// 创建一个带有头结点head的链表
ListNode head=new ListNode();
// 通过结点node来依次创建
ListNode node=head;
// 进位为so
int so=0;
// 遍历两个链表
while(l1!=null||l2!=null){
// val来记录每个对应的结点及进位的和
int val=so;
if(l1){
val+=l1.val;
}
if(l2){
val+=l2.val;
}
// 创建新结点并记录
node.next=new ListNode(val%10);
// 记录下一个进位
so=val/10;
// 错误点一:忘记遍历后序结点
}
if(so!=0){
node.next=new ListNode(so);
}
return head.next;
}
};
正确的解法:
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
// 创建一个带有头结点head的链表
ListNode head=new ListNode();
// 通过结点node来依次创建
ListNode node=head;
// 进位为so
int so=0;
// 遍历两个链表
while(l1!=null||l2!=null){
// val来记录每个对应的结点及进位的和
int val=so;
if(l1!=null){
val+=l1.val;
}
if(l2!=null){
val+=l2.val;
}
// 创建新结点并记录
node.next=new ListNode(val%10);
node=node.next;
// 记录下一个进位
so=val/10;
/*
遍历的时候要着重注意的点:
遍历下一个结点的时候
需要先判断当前的这个结点
是不是空结点
*/
// 遍历链表l1的下一个结点
if(l1!=null)
l1=l1.next;
// 遍历链表l2的下一个结点
if(l2!=null){
l2=l2.next;
}
}
if(so!=0){
node.next=new ListNode(so);
}
return head.next;
}
}