更多LeetCode题解
My Solution
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* result = new ListNode(0);
ListNode* result_bak = result;
int carry = 0;
int value = 0;
//add the first two nodes
result->val = (l1->val + l2->val + carry) % 10;
carry = (l1->val + l2->val + carry) / 10;
result->next = NULL;
//add subsequent nodes one by one until one of the list ends
while (l1->next != NULL && l2->next != NULL) {
value = (l1->next->val + l2->next->val + carry) % 10;
carry = (l1->next->val + l2->next->val + carry) / 10;
ListNode* l = new ListNode(value);
result->next = l;
result = result->next;
l1 = l1->next;
l2 = l2->next;
}
//the following three if are all three conditions while one of or both the two lists end.
if (l1->next == NULL && l2->next == NULL) {
if (carry) {
ListNode* l = new ListNode(1);
result->next = l;
}
}
if (l1->next != NULL) {
while (l1->next != NULL) {
value = (l1->next->val + carry) % 10;
carry = (l1->next->val + carry) / 10;
ListNode* l = new ListNode(value);
result->next = l;
result = result->next;
l1 = l1->next;
}
if (carry) {
ListNode* l = new ListNode(1);
result->next = l;
}
}
if (l2->next != NULL) {
while (l2->next != NULL) {
value = (l2->next->val + carry) % 10;
carry = (l2->next->val + carry) / 10;
ListNode* l = new ListNode(value);
result->next = l;
result = result->next;
l2 = l2->next;
}
if (carry) {
ListNode* l = new ListNode(1);
result->next = l;
}
}
return result_bak;
}
};
注意点
由于返回的是局部变量指针,因此每一个ListNode
都必须使用new
建立在堆上。
代码臃肿的原因
- 将
l1
,l2
同时到达尾部,有一个到达尾部的情况分开讨论了。 - 由于
result
的初始节点为0,我的想法是必须用l1
l2
的初始节点的和覆盖,由此多了while开头的操作。实际上只要在返回的时候返回头结点后一个节点就可以了
第一步简化
去掉了分情况讨论
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *dummyHead = new ListNode(0);
ListNode *p = l1, *q = l2, *curr = dummyHead;
int carry = 0;
int x = p->val;
int y = q->val;
carry = (x + y) / 10;
curr->val = (x + y) % 10;
curr->next = NULL;
while (p->next != NULL || q->next != NULL)
{
//assure that value of the nodes have been added before the pointer points to it
//if not, it will be troublesome to add value of the last node
x = (p->next != NULL) ? (p->next->val) : 0;
y = (q->next != NULL) ? (q->next->val) : 0;
ListNode* l = new ListNode((x + y + carry) % 10);
carry = (x + y + carry) / 10;
curr->next = l;
curr = curr->next;
if (p->next != NULL) p = p->next;
if (q->next != NULL) q = q->next;
}
if (carry)
{
ListNode* l = new ListNode(1);
curr->next = l;
}
return dummyHead;
}
};
第二步简化
去掉了while之前的头结点处理
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *dummyHead = new ListNode(0);
ListNode *p = l1, *q = l2, *curr = dummyHead;
int carry = 0;
while (p != NULL || q != NULL)
{
int x = (p != NULL) ? (p->val) : 0;
int y = (q != NULL) ? (q->val) : 0;
ListNode* l = new ListNode((x + y + carry) % 10);
carry = (x + y + carry) / 10;
curr->next = l;
curr = curr->next;
if (p != NULL) p = p->next;
if (q != NULL) q = q->next;
}
if (carry)
{
curr->next = new ListNode(1);
}
return dummyHead->next;
}
};
伪代码如下:
- 将当前结点初始化为返回列表的哑结点。
- 将进位
carry
初始化为0
。 - 将
p
和q
分别初始化为列表l1
和l2
的头部。- 遍历列表
l1
和l2
直至到达它们的尾端。 - 将
x
设为结点p
的值。如果p
已经到达l1
的末尾,则将其值设置为0
。 - 将
y
设为结点q
的值。如果q
已经到达l2
的末尾,则将其值设置为0
。 - 设定
sum = x + y + carry
。 - 更新进位的值,
carry = sum / 10
。 - 创建一个数值为
(sum mod 10)
的新结点,并将其设置为当前结点的下一个结点,然后将当前结点前进到下一个结点。 - 同时,将
p
和q
前进到下一个结点。
- 遍历列表
- 检查
carry = 1
是否成立,如果成立,则向返回列表追加一个含有数字1
的新结点。 - 返回哑结点的下一个结点。
使用二级指针
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int sum = 0;
ListNode *l3 = NULL;
ListNode **node = &l3;
while (l1 != NULL || l2 != NULL || sum>0)
{
if (l1 != NULL)
{
sum += l1->val;
l1 = l1->next;
}
if (l2 != NULL)
{
sum += l2->val;
l2 = l2->next;
}
(*node) = new ListNode(sum % 10);
sum /= 10;
node = &((*node)->next);
}
return l3;
}
};
python递归解法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode, c = 0) -> ListNode:
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
val = l1.val + l2.val + c
c = val // 10
ret = ListNode(val % 10 )
if (l1.next != None or l2.next != None or c != 0):
if l1.next == None:
l1.next = ListNode(0)
if l2.next == None:
l2.next = ListNode(0)
ret.next = self.addTwoNumbers(l1.next,l2.next,c)
return ret
转换为字符串,偷懒的方法
class Solution:
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
str_l1, str_l2 = '', ''
while l1:
str_l1 += str(l1.val)
l1 = l1.next
while l2:
str_l2 += str(l2.val)
l2 = l2.next
int_l1 = int(str_l1[::-1])
int_l2 = int(str_l2[::-1])
return list(map(int, str(int_l1 + int_l2)[::-1]))