1.题目
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
2.我的解题思路
第一次拿到这个题目个人认为是写起来别扭的链表应用题,由于没有说链表有多长,我很早就放弃了转成int的思路。我解题的时候,就是简单的思路:以长的链表为基础加短的链表,然后处理长的链表和进位,最后如果还有进位处理进位。我承认办法很土,没啥巧妙,以下贴出勉强能AC的代码:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode resultListNodeHead = null;
ListNode l1Pointer = l1;
ListNode l2Pointer = l2;
while (l1Pointer != null && l2Pointer != null) {
l1Pointer = l1Pointer.next;
l2Pointer = l2Pointer.next;
}
ListNode longerListPointer = l1;
ListNode shorterListPointer = l2;
if (l2Pointer != null) {
// l2 longer
longerListPointer = l2;
shorterListPointer = l1;
}
resultListNodeHead = longerListPointer;
ListNode resultListNodeHeadForCreate = longerListPointer;
// 遍历长链表,加短链表
int carry = 0;
while (shorterListPointer != null) {
int shortVal = shorterListPointer.val;
int longerVal = longerListPointer.val;
int resultVal = shortVal + longerVal + carry;
if (carry == 1) {
carry = 0;
}
if (resultVal >= 10) {
resultVal -= 10;
carry = 1;
}
longerListPointer.val = resultVal;
longerListPointer = longerListPointer.next;
shorterListPointer = shorterListPointer.next;
}
// 处理长链表和进位
while (longerListPointer != null) {
int longerVal = longerListPointer.val;
int resultVal = longerVal + carry;
if (carry == 1) {
carry = 0;
}
if (resultVal >= 10) {
resultVal -= 10;
carry = 1;
}
longerListPointer.val = resultVal;
longerListPointer = longerListPointer.next;
}
// 若还有进位没有处理,添加
if (carry == 1) {
if (longerListPointer == null) {
while (resultListNodeHeadForCreate != null) {
if (resultListNodeHeadForCreate.next == null) {
resultListNodeHeadForCreate.next = new ListNode(1);
break;
} else {
resultListNodeHeadForCreate = resultListNodeHeadForCreate.next;
}
}
} else {
int resultVal = longerListPointer.val + 1;
if (resultVal == 10) {
longerListPointer.val = 0;
longerListPointer.next = new ListNode(1);
} else {
longerListPointer.val = resultVal;
}
}
}
return resultListNodeHead;
}
3. 官方解答
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
ListNode p = l1, q = l2, curr = dummyHead;
int carry = 0;
while (p != null || q != null) {
int x = (p != null) ? p.val : 0;
int y = (q != null) ? q.val : 0;
int sum = carry + x + y;
carry = sum / 10;
curr.next = new ListNode(sum % 10);
curr = curr.next;
if (p != null) p = p.next;
if (q != null) q = q.next;
}
if (carry > 0) {
curr.next = new ListNode(carry);
}
return dummyHead.next;
}
4. 感想
4.1.不考虑哪个更长,不够长的补为0
链表相加的问题,必然会有长链短链,但我们只需要处理到链表末尾,给出最终结果即可,不需要过程,所以不需要得知哪个链更长。那不够长的链表如何变得和长链表一样长呢?补充0!对应答案中的代码:
while (p != null || q != null) {
int x = (p != null) ? p.val : 0;
int y = (q != null) ? q.val : 0;
4.2.多申请一个无用的头节点
本题中的链表很别扭,构造函数必须给一个值,让我下意识跟随题目的引导去编程。其实应当声明一个无用的头节点,然后.next的方式返回答案即可。对应答案中的代码:
ListNode dummyHead = new ListNode(0);
...
return dummyHead.next;
来源:oschina
链接:https://my.oschina.net/hengbao666/blog/4550050