LeetCode445两数相加II

题目链接

https://leetcode-cn.com/problems/add-two-numbers-ii/

题解一

  • 使用了栈,遍历链表把结点存入栈中,然后弹栈将结点相加,注意进位
  • 自己写的思路,代码有些长,应该有递归解法
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Problem: LeetCode 445
// URL: https://leetcode-cn.com/problems/add-two-numbers-ii/description/
// Tags: Linked List Stack Recursion
// Difficulty: Medium

#include <iostream>
#include <stack>
using namespace std;

struct ListNode{
int val;
ListNode* next;
ListNode(int x=0) : val(x), next(nullptr) {}
};

class Solution{
private:
int carry=0; // 进位

ListNode* addNode(ListNode* node1, ListNode* node2){
int sum = node1->val + node2->val + this->carry;
node1->val = sum%10;
this->carry = sum / 10;
delete node2;
return node1;
}

public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
stack<ListNode*> s1; // 使用引用是为了避免不必要的内存开销
stack<ListNode*> s2;
// 将两个链表中的结点存入栈中
while (l1!=nullptr){
s1.push(l1);
l1 = l1->next;
}
while (l2!=nullptr){
s2.push(l2);
l2 = l2->next;
}
ListNode *newHead;
// 将两个链表等长的部分相加
while (!s1.empty() && !s2.empty()){
newHead = this->addNode(s1.top(), s2.top());
s1.pop();
s2.pop();
}
// 如果两个链表不等长,则处理两个链表因不等长而剩余的结点
if (s1.empty()) s1 = s2;
ListNode *tempNode;
while(!s1.empty()){
// 取出一个结点
tempNode = s1.top();
s1.pop();
// 考虑进位
int sum = tempNode->val + this->carry;
tempNode->val = sum%10;
this->carry = sum/10;
// 将该结点加入链表
tempNode->next = newHead;
newHead = tempNode;
}
// 考虑最后一次进位
if (this->carry > 0){
// 将该结点加入链表
tempNode = new ListNode(this->carry);
tempNode->next = newHead;
newHead = tempNode;
}
return newHead;
}
};

题解二

  • 递归解法
  • 需要向短链表中添加结点使其与长链表长度一致,然后递归使链表相加
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Problem: LeetCode 445
// URL: https://leetcode-cn.com/problems/add-two-numbers-ii/description/
// Tags: Linked List Stack Recursion
// Difficulty: Medium

#include <iostream>
using namespace std;

struct ListNode{
int val;
ListNode* next;
ListNode(int x=0) : val(x), next(nullptr) {}
};

class Solution{
private:
int carry = 0; // 进位

// 遍历求出链表l有几个结点
int getLen(ListNode* l){
int len=0;
while(l!=nullptr){
len++;
l = l->next;
}
return len;
}

// 为链表l添加num个值为0的结点
ListNode* addZeroNodes(ListNode* l, int num){
if(num<=0) return l;
ListNode* temp;
while(num--){
temp = new ListNode(0);
temp->next = l;
l = temp;
}
return l;
}

// 递归函数
ListNode* addTwoLists(ListNode* l1, ListNode* l2){
if(l1==nullptr || l2==nullptr) return nullptr;
// 先使后面的结点相加
addTwoLists(l1->next, l2->next);
// 将两个结点相加
int sum = l1->val + l2->val + this->carry;
l1->val = sum%10;
this->carry = sum/10;
// 释放l2返回l1
delete l2;
return l1;
}

public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
// 使两个链表等长
int len1=this->getLen(l1), len2=this->getLen(l2);
l1 = this->addZeroNodes(l1, len2 - len1);
l2 = this->addZeroNodes(l2, len1 - len2);
// 通过递归使链表相加
l1 = addTwoLists(l1, l2);
// 考虑最后一个进位
if(this->carry > 0){
ListNode* temp = new ListNode(this->carry);
temp->next = l1;
return temp;
}
return l1;
}
};

作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!