Leetcode_20 天编程能力基础_day15

还是两道链表题。

2. Add Two Numbers

Analysis

披着链表外壳的大数加法题,算是模拟加法与合并链表两个题的结合版。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *L = new ListNode();
ListNode *p = L;
int carry = 0;
while(l1 != nullptr && l2 != nullptr) {
int sum = l1->val + l2->val + carry;
if(sum > 9) {
sum -= 10;
carry = 1;
} else carry = 0;
ListNode *tmp = new ListNode(sum);
p->next = tmp;
p = tmp;
l1 = l1->next;
l2 = l2->next;
}
while(l1 != nullptr) {
int sum = l1->val + carry;
if(sum > 9) {
sum -= 10;
carry = 1;
} else carry = 0;
ListNode *tmp = new ListNode(sum);
p->next = tmp;
p = tmp;
l1 = l1->next;
}
while(l2 != nullptr) {
int sum = l2->val + carry;
if(sum > 9) {
sum -= 10;
carry = 1;
} else carry = 0;
ListNode *tmp = new ListNode(sum);
p->next = tmp;
p = tmp;
l2 = l2->next;
}
if(carry) {
ListNode *tmp = new ListNode(carry);
p->next = tmp;
}
p = L;
L = L->next;
delete(p);
return L;
}
};

这样写虽然很思路清楚,但是看着很繁琐(主要是太长),改短一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *L = new ListNode();
ListNode *p = L;
int carry = 0;
while(l1 != nullptr || l2 != nullptr) {
int n1 = l1 != nullptr ? l1->val : 0;
int n2 = l2 != nullptr ? l2->val : 0;
int sum = n1 + n2 + carry;
ListNode *tmp = new ListNode(sum % 10);
carry = sum / 10;
p->next = tmp;
p = tmp;
if(l1 != nullptr) l1 = l1->next;
if(l2 != nullptr) l2 = l2->next;
}
if(carry) p->next = new ListNode(carry);
p = L;
L = L->next;
delete(p);
return L;
}
};

445. Add Two Numbers II

Analysis

这是上个题的升级版,差别在于这里将数字的每一位正序存在链表中了,所以计算之前得先逆置链表。

Code

直接把上面的代码与原来写过的反转链表代码抄过来😂。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
l1 = reverseList(l1);
l2 = reverseList(l2);
return reverseList(addTwoNumbers1(l1, l2));
}
ListNode* addTwoNumbers1(ListNode* l1, ListNode* l2) {
ListNode *L = new ListNode();
ListNode *p = L;
int carry = 0;
while(l1 != nullptr || l2 != nullptr) {
int n1 = l1 != nullptr ? l1->val : 0;
int n2 = l2 != nullptr ? l2->val : 0;
int sum = n1 + n2 + carry;
ListNode *tmp = new ListNode(sum % 10);
carry = sum / 10;
p->next = tmp;
p = tmp;
if(l1 != nullptr) l1 = l1->next;
if(l2 != nullptr) l2 = l2->next;
}
if(carry) p->next = new ListNode(carry);
p = L;
L = L->next;
delete(p);
return L;
}
ListNode* reverseList(ListNode* head) {
if(head == nullptr) return nullptr;
ListNode* L = new ListNode(0);
ListNode *p = L, *t = L;
while(head) {
t = head;
head = head->next;
t->next = p->next;
p->next = t;
}
p = L;
p = p->next;
delete(L);
return p;
}
};

还有一个进阶提示是不反转链表如何做。如果不反转链表的话,可以用栈来保存链表节点,然后依次取栈顶结点来进行计算,计算思路与上一个题是一样的。不过为了直接得到正序的结果,在构造新链表的时候,需要将最先插入的结点放到最后面,所以这里的指针使用与上一个题不一样(实际上就是链表的另一种建立方法)。偷个懒,不写了吧😁。

Summary

感觉链表的题做的有点乏味,因为是基础的缘故,好像也没有编一些复杂数据结构的题到这个系列吗?


Buy me a coffee ? :)
0%