【数据结构与算法】LeetCode:二叉树

news/2024/10/4 10:08:51 标签: leetcode, c++

文章目录

  • 二叉树
    • 前序遍历
      • 二叉树的前序遍历
      • 二叉树展开为链表 (Hot 100)
    • 中序遍历
      • 二叉树的中序遍历 (Hot 100)
      • 验证二叉搜索树 (Hot 100)
      • 二叉搜索树中第K小的元素 (Hot 100)
    • 后序遍历
      • 二叉树的后序遍历
    • 层序遍历
      • 二叉树的层序遍历 (Hot 100)
      • 二叉树的最大深度
      • 翻转二叉树 (Hot 100)
      • 二叉树的右视图 (Hot 100)
      • 二叉树的锯齿形层序遍历

二叉树

前序遍历(Pre-order Traversal)、中序遍历(In-order Traversal)、后序遍历(Post-order Traversal)和层序遍历(Level-order Traversal)是四种常见的遍历树形结构的方法。四种遍历方法的主要区别在于它们访问节点的顺序不同。

  • 前序遍历 首先访问根节点,然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然遵循前序遍历的规则。

  • 中序遍历 首先遍历左子树,然后访问根节点,最后遍历右子树。在遍历左、右子树时,仍然遵循中序遍历的规则。

  • 后序遍历 首先遍历左子树,然后遍历右子树,最后访问根节点。在遍历左、右子树时,仍然遵循后序遍历的规则。

前序、中序和后序遍历常用于对树形结构进行深度优先搜索(DFS)。通常使用递归或栈迭代来实现。

  • 层序遍历 从根节点开始,首先访问第一层节点,然后逐层向下访问。在同一层中,按照从左到右的顺序访问节点。

层序遍历常用于对树形结构进行广度优先搜索(BFS),通常使用队列迭代来实现。

前序遍历

二叉树的前序遍历

二叉树的前序遍历

递归:

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == nullptr) return; // 递归终止条件
        vec.push_back(cur->val);    // 中
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

迭代:

class Solution {
public:
    vector<int>preorderTraversal(TreeNode* root){
        stack<TreeNode*> st;
        vector<int> result;
        if(root == nullptr) return result;
        st.push(root);
        while(!st.empty()){
            TreeNode* node = st.top();  // 根节点出栈
            st.pop();
            result.push_back(node->val);
            if(node->right) st.push(node->right); // 右子树入栈,
            if(node->left) st.push(node->left);  // 左子树入栈
        }
        return result;
    }
};

二叉树展开为链表 (Hot 100)

二叉树展开为链表

class Solution {
public:
    void flatten(TreeNode* root) {
        vector<TreeNode*> node_list;
        // 前序遍历
        preorderTraversal(root, node_list); 
        // 连接
        for(int i = 1; i < node_list.size(); i++){
            TreeNode* pre = node_list[i - 1], *cur = node_list[i];
            pre->left = nullptr;
            pre->right = cur;
        }
    }
    void preorderTraversal(TreeNode* root, vector<TreeNode*> & node_list){
        if(root == nullptr) return;
        node_list.push_back(root);
        preorderTraversal(root->left, node_list);
        preorderTraversal(root->right, node_list);
    }
};

中序遍历

二叉树的中序遍历 (Hot 100)

二叉树的中序遍历
递归

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == NULL) return;
        traversal(cur->left, vec);  // 左
        vec.push_back(cur->val);    // 中
        traversal(cur->right, vec); // 右
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

迭代

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root){
        vector<int> result;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while(cur != nullptr || !st.empty()){
            if(cur != nullptr){
                st.push(cur);
                cur = cur->left;
            }else{
                cur = st.top();
                st.pop();
                result.push_back(cur->val);
                cur = cur->right;
            }
        }
        return result;
    }
};

验证二叉搜索树 (Hot 100)

验证二叉搜索树
二叉搜索树的中序遍历为递增序列

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> stack;
        long long inorder = (long long)INT_MIN - 1;
        TreeNode* cur = root;
        while (!stack.empty() || cur != nullptr) {
            while (cur != nullptr) {
                stack.push(cur);
                cur = cur -> left;
            }
            cur = stack.top();
            stack.pop();
            // 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树
            if (cur -> val <= inorder) {
                return false;
            }
            inorder = cur -> val;
            cur = cur -> right;
        }
        return true;
    }
};

二叉搜索树中第K小的元素 (Hot 100)

二叉搜索树中第K小的元素

class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        stack<TreeNode *> stack;
        TreeNode* cur = root;
        while (cur != nullptr || stack.size() > 0) {
            while (cur != nullptr) {
                stack.push(cur);
                cur = cur->left;
            }
            cur = stack.top();
            stack.pop();
            --k;
            if (k == 0) {
                break;
            }
            cur = cur->right;
        }
        return cur->val;
    }
};

后序遍历

二叉树的后序遍历

二叉树的后序遍历
递归:

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == nullptr) return;
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
        vec.push_back(cur->val);    // 中
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

迭代:中右左遍历,然后reverse得到左右中

class Solution {
public:
    vector<int>postorderTraversal(TreeNode* root){
        stack<TreeNode*> st;
        vector<int> result;
        if(root==NULL) return result;
        st.push(root);
        while(!st.empty()){
            TreeNode* node = st.top();
            st.pop();
            result.push_back(node->val);
            if(node->left) st.push(node->left);
            if(node->right) st.push(node->right);
        }
        reverse(result.begin(), result.end());
      
        return result;

    }
};

层序遍历

二叉树的层序遍历 (Hot 100)

二叉树的层序遍历

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> que;
        if(root != nullptr) que.push(root);
        vector<vector<int>> result;
        while(!que.empty()){
            int size = que.size(); // 每一层的节点个数
            vector<int> vec;
            for(int i = 0; i < size; i++){
                TreeNode* node = que.front();
                que.pop();
                vec.push_back(node->val);
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
            result.push_back(vec);
        }
        return result;
    }
};

二叉树的最大深度

二叉树的最大深度

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (root == NULL) return 0;
        int depth = 0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()) {
            int size = que.size();
            depth++; // 记录深度
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return depth;
    }
};

翻转二叉树 (Hot 100)

翻转二叉树

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                swap(node->left, node->right); // 节点处理
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return root;
    }
};

二叉树的右视图 (Hot 100)

二叉树的右视图

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<int> result;
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                // 将每一层的最后元素放入result数组中
                if (i == (size - 1)) result.push_back(node->val); 
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return result;
    }
};

二叉树的锯齿形层序遍历

二叉树的锯齿形层序遍历

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        queue<TreeNode*> que;
        vector<vector<int>> res;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            vector<int> tmp;
            for(int i = que.size(); i > 0; i--) {
                TreeNode* node = que.front();
                que.pop();
                tmp.push_back(node->val);
                if (node->left != NULL) que.push(node->left);
                if (node->right != NULL) que.push(node->right);
            }
            if (res.size() % 2 == 1) reverse(tmp.begin(),tmp.end());
            res.push_back(tmp);
        }
        return res;
    }
};

http://www.niftyadmin.cn/n/5689813.html

相关文章

哪家宠物空气净化器可以高效去除浮毛?希喂、IAM、有哈怎么样

在现代养宠家庭中&#xff0c;随着生活节奏的加快&#xff0c;清理浮毛也是很多家庭周末必须要做的事情。但是如何选择一款吸毛好、还不增加清理负担的宠物空气净化器&#xff0c;在寸土寸金的租房里为全家老小的健康生活保障&#xff1f;又如何通过强大的吸毛、除臭技术和除菌…

Kali或Debian系统安装JDK1.8保姆级教程

一、下载JDK1.8 先到Oracle的官网下载JDK1.8 Java Archive | Oraclehttps://www.oracle.com/java/technologies/downloads/archive/Java Archive Downloads - Java SE 8

FiBiNET模型实现推荐算法

1. 项目简介 A031-FiBiNET模型项目是一个基于深度学习的推荐系统算法实现&#xff0c;旨在提升推荐系统的性能和精度。该项目的背景源于当今互联网平台中&#xff0c;推荐算法在电商、社交、内容分发等领域的广泛应用。推荐系统通过分析用户的历史行为和兴趣偏好&#xff0c;预…

Java后端中的分布式事务实现:从XA到TCC的演进

Java后端中的分布式事务实现&#xff1a;从XA到TCC的演进 大家好&#xff0c;我是微赚淘客返利系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来聊聊Java后端开发中非常重要的一个话题——分布式事务。随着微服务架构的流行…

Vue 技术进阶 day2 数据监视的原理、其他内置指令、自定义指令、生命周期、组件化、VueComponent构造函数

目录 1.Vue监测数据的原理 1.1 原理 1.1.1 数据劫持 1.1.2 观察者模式(Vue内部的实现) 1.1.3 更新组件 1.1.4 计算属性和侦听器 1.2 后添加属性做响应式&#xff08;Vue.set / vm.$set&#xff09; 1.3 对象和数组的响应式 1.4 数据监视案例 2.指令 2.1 内置指令 2.…

计算机科学英语词汇汇总(下)Computer Science English Complete Vocabulary )

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

CSS实现服务卡片

CSS实现服务卡片 效果展示 CSS 知识点 回顾整体CSS知识点灵活运用CSS知识点 页面整体布局 <div class"container"><div class"card"><div class"box"><div class"icon"><ion-icon name"color-pal…

安卓真机调试“no target device found“以及“ INSTALL_FAILED_USER_RESTRICTED“两个问题的解决办法

目录 1 no target device found问题解决办法 2 “INSTALL_FAILED_USER_RESTRICTED”解决办法 使用android studio 2023.2.1.23windows版本。手机为小米K70 Pro 1 no target device found问题解决办法 参考小米手机如何开启usb调试功能&#xff1f; (baidu.com) 1 联接手机…