20.哀家要长脑子了!

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;
    }
};

 我发现做过的题,老是不记得,就像这个反转链表

是不是要时时回过头想一想看一看,还是我没有彻底搞懂,囫囵吞枣,一知半解,似懂非懂。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值