445 两数相加Ⅱ
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
如果不使用反转链表,答案给出的解决方案是使用栈stack。利用栈先进后出的特点,将链表反转输出
思路:
- 存入stack
- 同时输出,计算和sum&进位carry,
- 逆序建立链表:
Listnode* head = nullptr;
while(...){
Listnode* node = new Listnode(num);
node->next = head;//理解为反转链表的cur->next = prev;
head = node;//prev = cur;
}
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
stack<int> s1, s2;
while(l1){
s1.push(l1->val);
l1 = l1->next;
}
while(l2){
s2.push(l2->val);
l2 = l2->next;
}
ListNode* curr = nullptr;
int carry = 0 ;
while(!s1.empty()||!s2.empty()||carry){
int a = s1.empty()?0:s1.top();
int b = s2.empty()?0:s2.top();
int sum = a + b + carry;
if(!s1.empty())s1.pop();
if(!s2.empty())s2.pop();
carry = sum / 10;
sum %= 10;
//在头部和已建立的节点中插入新节点。
ListNode* node = new ListNode(sum);
node->next = curr;
curr = node;
}
return curr;
}
};
c++代码学习:栈的入和出
stack<int> sta;
sta.push(x);//入栈
sta.pop();//顶端出栈
x = sta.top();//获取最顶端的数
21 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
思路:归并排序
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (!l1) return l2;
if (!l2) return l1;
ListNode* dum = new ListNode(0); // 哑节点
ListNode* cur = dum;
while(l1 && l2){
if(l1->val < l2->val){
cur->next = l1;
l1 = l1->next;
}else{
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
/* while(l1){
cur->next = l1;
l1 = l1->next;
cur = cur->next;
}
while(l2){
cur->next = l2;
l2 = l2->next;
cur = cur->next;
}*/
// 如果有剩余节点,直接连接到结果链表的末尾
cur->next = l1 ? l1 : l2;
ListNode* newHead = dum->next;
delete dum;
return newHead;
}
};
review 归并排序的模板
void merge_sort(int q[], int l, int r) {
if (l >= r) return;
int mid = l + r >> 1; // 计算中点
merge_sort(q, l, mid); // 递归排序左半部分
merge_sort(q, mid + 1, r); // 递归排序右半部分
int k = 0, i = l, j = mid + 1;
// 合并两个有序的子数组
while (i <= mid && j <= r) {
if (q[i] <= q[j]) tmp[k++] = q[i++];
else tmp[k++] = q[j++];
}
// 将左半部分剩余元素复制到临时数组
while (i <= mid) tmp[k++] = q[i++];
// 将右半部分剩余元素复制到临时数组
while (j <= r) tmp[k++] = q[j++];
// 将合并后的有序数组复制回原数组
for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
}