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的情况,这是不允许的;


猜你喜欢

转载自blog.csdn.net/Errors_In_Life/article/details/79063667