1.114. 二叉树展开为链表 - 力扣(LeetCode)
是这么一个过程:
- 如果根节点不为空,然后左子树也不为空,先找到左子树最右边的结点
- 把根节点的右子树变成左子树最右边结点的右孩子
- 把根节点的左子树变为根节点的右子树,左子树可以置为空了
- 迭代根节点,下一个需要操作改变的是根节点的右子树的根节点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void flatten(TreeNode* root) {
while(root != nullptr){
if(root->left != nullptr){
auto most_right = root->left;
while(most_right->right != nullptr) most_right = most_right->right;
most_right->right = root->right;
root->right = root->left;
root->left = nullptr;
}
root = root->right;
}
return;
}
};
2.61. 旋转链表 - 力扣(LeetCode)
以前做过旋转数组,但是。。。。。。你忘得干干净净小姐姐。。。
这个题的思路是:
- 先把这个链表首尾连起来,形成一个闭合循环链表
- 然后找到要断开的位置,将工作指针p指向答案链表头结点的前一个结点,也就是答案链表的尾结点
- 断开答案链表的首位结点(因为通过第一步我们把链表变成了一个闭合的环了
这个我觉得巧妙的点是:add = n - k % n 找断开的位置
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(k == 0 || head == nullptr || head->next == nullptr){
return head;
}
int n = 1;
ListNode *p = head;
while(p->next){
p = p->next;
n++;
}
int add = n-k % n;
if(add == n){
return head;
}
p->next = head;
while(add--){
p = p->next;
}
ListNode *ret = p->next;
p->next = nullptr;
return ret;
}
};
其实我每次首先都搞不懂这种循环取模操作 循环队列 上次那个旋转数组 还有蓝桥云课里面的题
3.2. 两数相加 - 力扣(LeetCode)
这个题我也觉得挺有意思的,还有种很熟悉的感觉,似曾相识,但是我又说不出。。。抱一丝
最关键的是这个carry!进位
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *head = nullptr, *tail = nullptr;
int carry = 0;
while(l1 || l2){
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 +carry;
if(!head){
head = tail = new ListNode(sum % 10);
}
else{
tail->next = new ListNode(sum % 10);
tail = tail->next;
}
carry = sum / 10;
if(l1){
l1 = l1->next;
}
if(l2){
l2 = l2->next;
}
}
// 如果倒数第二个结点元素还有进位的话 最后的结点的元素就是进位值啊
if(carry > 0){
tail->next = new ListNode(carry);
}
return head;
}
};
4.445. 两数相加 II - 力扣(LeetCode)
抱一丝哈抱一丝 我就是直接先两个链表反转 求出结果后在反转的
/**
* 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* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *prev = nullptr;
ListNode *cur = l1;
ListNode *next;
while(cur){
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
l1 = prev;
prev = nullptr;
cur = l2;
next = nullptr;
while(cur){
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
l2 = prev;
ListNode *head = nullptr, *tail = nullptr;
int carry = 0;
while(l1 || l2){
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 +carry;
if(!head){
head = tail = new ListNode(sum % 10);
}
else{
tail->next = new ListNode(sum % 10);
tail = tail->next;
}
carry = sum / 10;
if(l1){
l1 = l1->next;
}
if(l2){
l2 = l2->next;
}
}
if(carry > 0){
tail->next = new ListNode(carry);
}
// return head;
prev = nullptr;
cur = head;
next = nullptr;
while(cur){
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
return prev;
}
};
我发现做过的题,老是不记得,就像这个反转链表
是不是要时时回过头想一想看一看,还是我没有彻底搞懂,囫囵吞枣,一知半解,似懂非懂。。。