- 題目描述
給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,並且它們的每個節點只能存儲 一位 數字。
如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。
您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 輸出:7 -> 0 -> 8 原因:342 + 465 = 807
- 思路理解
題目很容易理解,就是簡單的鏈表操作,但是想要考慮到所有的情況,那麼就有點複雜了,主要有以下幾種情況:
- 不能另外開闢新的鏈表(我第一次做就是因爲開闢新的鏈表,導致他說“超出內存限制”)
- 由於不能開闢新的內存空間,那麼只能將兩個鏈表的每個節點之和放在其中一個鏈表上。
- 長度l1>l2或者l1<l2或者l1=l2
- 如果單獨要執行一次循環找出兩個鏈表的長度的話,時間超時(我試過先求兩個鏈表的各自長度,然後將之和放在較長的那個鏈表上,但是系統提示我說“超出時間限制”,真的很難受(真是苛刻,時間複雜度O(2n)都不行,必須要求時間複雜度爲O(n),咦~噁心~嗬呸!)
- 解決方案
我是首先把所有的和都放在鏈表list1上,不管len(list1)>len(list2)還是len(list1)<=len(list2);
- 如果len(list1)>len(list2),那是最好的,直接把所有每一位之和放在list1上就可以。(注意進位標誌)
- 如果len(list1)=len(list2),那麼就直接放在list1上面,也要注意進位,這樣的話需另外開闢一個空間存放最高位的進位。
- 如果len(list1)=len(list2),這就比較麻煩了,怎麼辦呢,我就把list1的最後一個節點的next指向list2的後面的節點地址。(同樣注意進位問題)
只要將1,2,3這三種情況和進位問題整理好的話,那麼就可以寫代碼了。下面就是我的代碼。
時間複雜度O(n),空間複雜度爲O(1);
/**
* 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* nodeList1=l1;
ListNode* nodeList2=l2;
int digit=0;
bool flag=false;
//默認接到l1上面去
while(nodeList1->next!=nullptr&&nodeList2->next!=nullptr)
{
if(flag==true)
{
digit=nodeList1->val+nodeList2->val+1;
flag=false;
}
else
digit=nodeList1->val+nodeList2->val;
if(digit>=10)
{
digit=digit%10;
flag=true;
}
nodeList1->val=digit;
nodeList1=nodeList1->next;
nodeList2=nodeList2->next;
}
//l1和l2一樣長
if(nodeList1->next==nullptr&&nodeList2->next==nullptr)
{
if(flag==true)
{
digit=nodeList1->val+nodeList2->val+1;
flag=false;
}
else
digit=nodeList1->val+nodeList2->val;
if(digit>=10)
{
digit=digit%10;
flag=true;
}
nodeList1->val=digit;
if(flag==true)
{
ListNode* newNode=new ListNode(1);
nodeList1->next=newNode;
}
return l1;
}
//l2是短的
if(nodeList2->next==nullptr)
{
if(flag==true)
{
nodeList1->val=nodeList1->val+nodeList2->val+1;
flag=false;
}
else
nodeList1->val=nodeList1->val+nodeList2->val;
if(nodeList1->val>=10)
{
nodeList1->val%=10;
flag=true;
}
nodeList1=nodeList1->next;
while(nodeList1->next!=nullptr)
{
if(flag==true)
{
nodeList1->val=nodeList1->val+1;
flag=false;
}
if(nodeList1->val>=10)
{
nodeList1->val%=10;
flag=true;
}
nodeList1=nodeList1->next;
}
//最後一個節點
if(flag==true)
{
nodeList1->val=nodeList1->val+1;
flag=false;
}
if(nodeList1->val>=10)
{
nodeList1->val%=10;
flag=true;
}
if(flag==true)
{
ListNode* newNode=new ListNode(1);
nodeList1->next=newNode;
flag=false;
}
return l1;
}
//l1是短的
if(nodeList1->next==nullptr)
{
if(flag==true)
{
digit=nodeList1->val+nodeList2->val+1;
flag=false;
}
else
digit=nodeList1->val+nodeList2->val;
if(digit>=10)
{
flag=true;
digit=digit%10;
}
nodeList1->val=digit;
nodeList1->next=nodeList2->next; //將l2後面節點接到l1後面
nodeList1=nodeList1->next;
while(nodeList1->next!=nullptr)
{
if(flag==true)
{
nodeList1->val++;
flag=false;
}
if(nodeList1->val>=10)
{
nodeList1->val%=10;
flag=true;
}
nodeList1=nodeList1->next;
}
//最後一個節點
if(flag==true)
{
nodeList1->val++;
flag=false;
}
if(nodeList1->val>=10)
{
nodeList1->val%=10;
flag=true;
}
if(flag==true)
{
ListNode* newNode=new ListNode(1);
nodeList1->next=newNode;
}
return l1;
}
}
};
。