• LC 填充每个节点的下一个右侧节点指针(迭代以及递归)


    给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

    struct Node {
    int val;
    Node *left;
    Node *right;
    Node *next;
    }

    填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

    初始状态下,所有 next 指针都被设置为 NULL。

    这道题目明显是关于层序遍历的题目,于是我也没想太多,直接套层序遍历的模板,但是还是需要注意一下边界的条件,编码的技巧也没太大的必要说,基本是基于模拟实现的的。

    class Solution {
    public:
        Node* connect(Node* root) {
            if (root == nullptr)
                return nullptr;
            // BFS
            queue<Node*> que;
            que.push(root);
            while (!que.empty()){
                int n = que.size();
                cout<<n<<endl;
                for (int i = 0; i < n; i++){
                    Node* temp = que.front();
                    que.pop();
                    if (temp->left)
                        que.push(temp->left);
                    if (temp->right)
                        que.push(temp->right);
    
                    if (i == n-1)
                        temp->next = nullptr;
                    else
                        temp->next = que.front();
                }
            }
            return root;
        }
    };
    

    但是递归的方法很有意思
    其实关于递归,这种递归属于前序遍历的递归,前序遍历以及后序遍历最大的区别就是,一个是自顶向下的处理问题,一个是自底向上的处理问题。

    • 关于自顶向下处理问题,其实都是有套路的,我们要处理一个较大的问题,那么先解决当前节点的问题,然后将问题划分开来,将划分后的问题递归的解决,当然我们划分之后的子问题的问题规模一定是不断变小的。所以在整个递归函数的时候需要设置好递归的出口。这种问题有一个典型的特点就是数据之间的耦合联系非常少。关于自顶向下的处理问题,一定要有一定的记忆化思维,明白我们要解决什么样的问题,另外我们在往下递进的时候,我们要意识到我们已经解决了一部分问题,利用已经解决的部分递进解决还没有解决的问题。

    • 关于自底向上的处理问题,我们需要开始时候不断的划分问题规模,将问题规模不断变小,然后减小到不能减小的时候,开始自底向下的不断解决问题,这里往往需要一个归并的操作,归并操作需要将每个小问题的解答连接起来。不断的连接,最后得到我们整个大问题的解答,一个典型的例子就是归并排序。

    class Solution {
    private:
        void traversal(Node* cur) {
            if (cur == NULL) return;
                                    // 中
            if (cur->left) cur->left->next = cur->right; // 操作1
            if (cur->right) {
                if (cur->next) cur->right->next = cur->next->left; // 操作2 
                else cur->right->next = NULL;
            }
            traversal(cur->left);   // 左
            traversal(cur->right);  // 右
        }
    public:
        Node* connect(Node* root) {
            traversal(root);
            return root;
        }
    };
    
  • 相关阅读:
    linux ssh 免密码登录
    Emacs Org Mode学习
    Emacs Org Mode学习
    java--for循环,一个分号的区别
    java--for循环,一个分号的区别
    【JVM.6】虚拟机类加载机制
    【JVM.5】类文件结构
    【JVM.4】调优案例分析与实战
    【JVM.3】虚拟机性能监控与故障处理工具
    【JVM.2】垃圾收集器与内存分配策略
  • 原文地址:https://www.cnblogs.com/wsl-hitsz/p/13819985.html
Copyright © 2020-2023  润新知