problem:
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Example
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8 Explanation: 342 + 465 = 807.
方法1:
思路:首先我會習慣性暴力解決一下:其實就是兩個數相加,很簡單,但是給你的結構式鏈表:所以就是鏈表和數字之間的轉換。
我們看到:第一個框框就是鏈表,已知;然後中間的框框就是轉化爲數字,簡單相加;然後第三個框框的return;難點(如果有)就在框框之間的轉換。
代碼展示:
/**
* 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) {
int num1=0,num2=0,i=0,j=0,ans=0;
if (l1 == NULL) return l2;
else if (l2 == NULL) return l1;
while(l1 != NULL)
{
num1 = num1+(10^i)*l1->val;
i++;
l1=l1->next;
}
while(l2 != NULL)
{
num2 = num2+(10^j)*l2->val;
j++;
l2=l2->next;
}
ans = num1+num2;
ListNode *answer = new ListNode(ans % 10);
answer->next = NULL;
ListNode *l3 = answer;
ans = ans/10;
answer = answer->next;
while(ans!=0);
{
answer->val = ans%10;
ans = ans/10;
answer = answer->next;
}
return l3;
}
};
分析:一進來定義i、j記錄兩個鏈表長度;num1、num2記錄兩個鏈表所記錄的數字;ans記錄相加數字的結果;answer記錄第三個鏈表,l3記錄返回的第三個鏈表的頭部;運行結果:
哈哈哈,時間限制超出範圍了;也就是運行時間太長了:這就是暴力解決問題的碰壁~~~
方法2、
思路:
可以看到,這個算法其實很沒有必要,沒有必要去轉化爲數字,只需要兩個鏈表逐個相加>>會遇到什麼問題>>如果兩者加需要進位怎麼辦>>那就多增加一個記錄加減進位的值就好了>>問題解決。
代碼:
/**
* 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) {
if (l1 == NULL) return l2;
else if (l2 == NULL) return l1;
int carry=0;
int ans = l1->val+l2->val;
ListNode* answer = new ListNode(ans%10);
ListNode* l3 = answer;
answer->next = NULL;
l1 = l1->next;
l2 = l2->next;
if(ans>=10) carry=1;
while(l1 || l2 || carry)
{
ans = (l1? l1->val:0)+(l2? l2->val:0)+carry;
answer->next = new ListNode(ans%10);
answer = answer->next;
carry = (ans >=10)? 1:0;
l1 = l1? l1->next:l1;
l2 = l2? l2->next:l2;
}
return l3;
}
};
分析:
方法2中、代碼前部分while之前,都是在定義第一個節點,while中只需要循環一次,並且考慮了兩條鏈表不一樣長的情況和最後一位需要進位的情況:而上面方法1,需要循環三次(三條鏈表);所以時間上放慢了三倍;
運行結果:容易錯誤:
ans = l1->val+l2->val+carry;
代替:
ans = (l1? l1->val:0)+(l2? l2->val:0)+carry;
就會出現,當l2或者l1某個節點爲NULL,而carry爲1的時候,出現NULL+int+int的情況,這是不允許的;