題目描述

示例提示

經驗教訓

連結串列題的判空條件不是萬能的,有時候示例會極其複雜,根本難以通過判空來區分不同情況。

/**

 \* 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作為基準連結串列,然後將長的連結串列的後半部分連結過來,這樣就增加了很多種處理情況給自己為難。