题目描述:给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。将两个数相加,返回新链表表示它们的和。
题目地址:https://leetcode-cn.com/problems/add-two-numbers/
解答
此题就是链表进行求和运算并返回新链表,基础就是模拟正常的算数,从低位到高位两数分别相加进位,进位用除10运算,新值用除10取余运算,需要注意与处理的问题就是如何应对两个链表长度不同,以及最后是否有进位的问题。代码及注释如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode * retList = new ListNode(0); //最后要返回的链表,注意表头不是要返回的值
auto tempList = retList; //给链表增值过程中用于指向链表尾的指针
int newVal; //将要新加入链表中的值
int val1; //代表从链表l1中取得的值
int val2; //代表从链表l2中取得的值
int carryBit = 0; //进位
while (l1 != nullptr || l2 != nullptr) {
if (l1 == nullptr) //当l1为空指针,设定其代表的值为0
val1 = 0;
else { //不为空指针设定值为链表内部的值,并且更新l1指向位置
val1 = l1->val;
l1 = l1->next;
}
if (l2 == nullptr)
val2 = 0;
else {
val2 = l2->val;
l2 = l2->next;
}
newVal = (val1 + val2 + carryBit) % 10;
carryBit = (val1 + val2 + carryBit) / 10;
tempList->next = new ListNode(newVal);
tempList = tempList->next;
}
//用于判断最后是否有一个进位
if (carryBit == 1) {
tempList->next = new ListNode(1);
}
return retList->next;
}
};
总结
1. 在链表中为了增强程序可读性,链表的第一个节点为无用的,这样做的缺点就是浪费了一个节点的内存以及最后返回值为retList->next而不是retList。
2. 在对val1和val2处理时通过判断是否到l1或l2尾部而对其进行赋0或具体值,避免了在while循环外部判断先到达哪一个链表的尾部,使程序更加简练。