题目描述
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零
解题
思路:
即:创建一个临时的头结点,并将指针cur指向该节点,之后遍历L1 和 L2两个链表,将他们对应位置节点的值相加,同和,如果该位置前的两个节点之和大于等于10,需要进位,则该节点值加1,然后对10取余,并新建节点保存,将cur的next指针指向该节点。
代码实现:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
//两数相加
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
//创建虚拟表头指针,默认为-1;
ListNode *res = new ListNode(-1);
//指向链表表头的指针,用于返回值
ListNode *cur = res;
ListNode *del = cur;
int carry = 0;
while (l1 || l2 )
{
//l1和l2当前位是否为空,不存在用0补上
int l1val = l1 ? l1->val : 0;
int l2val = l2 ? l2->val : 0;
int sum = l1val + l2val + carry;
carry = sum / 10;
// cur->next保存各位的数值
cur->next = new ListNode(sum % 10);
cur = cur->next;
if (l1) l1 = l1->next;
if (l2) l2 = l2->next;
}
//最高位有进位,在最前面补1
if (carry) cur->next = new ListNode(1);
return res->next;
free (del);
}
};
ListNode* createListNode(std::vector<int> vals);
void freeListNode(ListNode* head);
void printListNode(ListNode* head);
int main()
{
auto l1 = createListNode({1, 2, 3});
auto l2 = createListNode({9, 8, 7, 6});
printListNode(l1);
printListNode(l2);
Solution s;
auto sum = s.addTwoNumbers(l1, l2);
printListNode(sum);
freeListNode(l1);
freeListNode(l2);
freeListNode(sum);
return 0;
}
//链表创建
ListNode* createListNode(std::vector<int> vals)
{
//c11新特性, nullptr空指针类型的关键字
ListNode *res = nullptr;
ListNode *last = nullptr;
for(auto val : vals) {
if(last) {
last->next = new ListNode(val);
last = last->next;
}
else {
res = new ListNode(val);
last = res;
}
}
return res;
}
//链表输出
void printListNode(ListNode* head)
{
ListNode* node = head;
while(node) {
std::cout << node->val << ", ";
node = node->next;
}
std::cout << std::endl;
}
//释放内存
void freeListNode(ListNode* head)
{
ListNode* node = head;
while(node) {
auto temp = node->next;
delete node;
node = temp;
}
}
输出:
1, 2, 3,
9, 8, 7, 6,
0, 1, 1, 7,
小记
ListNode的结构:
struct ListNode {
int val; //当前结点的值
ListNode *next; //指向下一个结点的指针
ListNode(int x) : val(x), next(NULL) {} //初始化当前结点值为x,指针为空
};
- 在节点ListNode定义中,定义为节点为结构变量
- 节点存储了两个变量:value 和 next。value 是这个节点的值,next 是指向下一节点的指针,当 next 为空指针时,这个节点是链表的最后一个节点
- 注意val只代表当前指针的值,比如p->val表示p指针的指向的值;而p->next表示链表下一个节点,也是一个指针
- 构造函数包含两个参数 _value 和 _next ,分别用来给节点赋值和指定下一节点
几点注意点:
定义链表ListNode时,
链表的首个值不能为0,当首个参数为0时,代表着链表为空。
只需要定义一个ListNode xx = new ListNode(0);即可。即只定义一个空链表。
不需要定义长度 。
赋值时
通过xx.next = new ListNode(4);来赋值,注意此时是赋值给下一个指针指向的位置,此时此链表一个值,值为4。
通过一个链表指向原链表地址,赋值完成时,打印原链表的指针地址。获取所有值。(后面的打印想不太明白,有待研究)
取值时
取第一个值时,只需要xx.val即可。
取第二或之后的值时,需要xx = xx.next;int x = xx.val;这个方式取值。