LeetCode修仙:Add Two Numbers

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的情況,這是不允許的;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章