您的位置:首页 > 其它

LeetCode修仙:Add Two Numbers

2018-01-15 14:57 357 查看
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的情况,这是不允许的;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息