LeetCode2-链表两数和
题目描述

示例提示

经验教训
链表题的判空条件不是万能的,有时候示例会极其复杂,根本难以通过判空来区分不同情况。
/**
\* Definition for singly-linked list.
\* struct ListNode {
\* int val;
\* ListNode *next;
\* ListNode() : val(0), next(nullptr) {}
\* ListNode(int x) : val(x), next(nullptr) {}
\* ListNode(int x, ListNode *next) : val(x), next(next) {}
\* };
*/
class Solution {
public:
ListNode* AttachNode(ListNode* La, int temp){
if(1==temp){
ListNode* x = new ListNode;
x->val = 1;
La->next = x;
x->next = NULL;
}
return La;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {//新链表与l1共用
int temp=0;
ListNode *La=l1,*Lb=l2,*Lc=l1;
while(La&&Lb){//设置两个指针分别对l1和l2操作
La->val = La -> val + Lb -> val + temp;
if(La->val>=10){
temp = 1;
La->val-=10;
}
else{
temp = 0;
}
if(La->next&&Lb->next){
La = La -> next;
Lb = Lb -> next;
}
else{
break;
}
}
if(La->next==NULL&&Lb->next==NULL&&temp==1){
AttachNode(La,temp);
return l1;
}
if(1==temp){
if(Lb->next)La->next=Lb->next;
if(La->next){
La=La->next;
}
while(La){
//if(La->next==NULL&&Lb->next==NULL)break;
La->val += temp;
if(La->val>=10){
temp = 1;
La->val-=10;
}
else{
temp = 0;
}
if(La->next){
La = La->next;
}
else{
break;
}
}
}
// if(1==temp){
// ListNode* x = new ListNode;
// x->val = 1;
// La->next = x;
// x->next = NULL;
// }
AttachNode(La,temp);
return l1;
}
};
比如说
[5]
[5]
的情况与
[9,9,9,9]
[9,9,9]
的情况就无法区分(是指la->next为空且lb->next为空时,者要进行的操作是不一样的。)上述代码已经是想要两者兼顾了,但还是不行。
参考正解
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int size_1 = 0, size_2 = 0;
ListNode* temp = l1;
//统计l1长度
while(temp){
size_1++;
temp = temp->next;
}
//统计l2长度
temp = l2;
while(temp){
size_2++;
temp = temp->next;
}
//大于10的部分由remainder保留
int remainder = 0;
//longer指向最长的数组,shorter指向最短的;
ListNode* longer = (size_1 >= size_2) ? l1 : l2;
ListNode* shorter = (size_1 < size_2) ? l1 : l2;
//res指向最长的
//我们基于较长链进行操作
ListNode* res = longer;
//进行循环赋值
while(longer||shorter){
//长链先加上余数
longer->val += remainder;
//再加上短链
if(shorter){
longer->val += shorter->val;
}
//保留大于10的部分
if(longer->val > 9){
longer->val -= 10;
remainder = 1;
}
else{
remainder = 0;
}
//如果longer遍历到最后一位且大于10,末尾加上一个1的节点
//这里我是考虑到了,但是在我前面最终决定放弃的那个版本里产生了麻烦
if(longer->next == nullptr && remainder){
ListNode* ll = new ListNode(1);
longer->next = ll;
return res;
}
//继续走
longer = longer->next;
if(shorter){
shorter = shorter->next;
}
}
return res;
}
};
最大的问题就在于我在操作时没能就谁长谁短进行简化思考,觉得无端的遍历一遍链表很亏。所以只是随便挑选l1作为基准链表,然后将长的链表的后半部分链接过来,这样就增加了很多种处理情况给自己为难。

浙公网安备 33010602011771号