首页 > 编程语言 >代码随想录算法训练营第十三天|Day13二叉树

代码随想录算法训练营第十三天|Day13二叉树

时间:2024-10-12 20:19:31浏览次数:3  
标签:right TreeNode struct 随想录 queue 二叉树 left root 第十三天

226.翻转二叉树

题目链接/文章讲解/视频讲解:https://programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html

思路

只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果

递归法

struct TreeNode* invertTree(struct TreeNode* root){
    if(!root)
        return NULL;
    struct TreeNode* temp = root->right;
    root->right = root->left;
    root->left = temp;
    invertTree(root->left);
    invertTree(root->right);
    return root;
}

迭代法

struct TreeNode* invertTree(struct TreeNode* root){
    if(!root)
        return NULL;
    struct TreeNode** stack = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 100);
    int stackTop = 0;
    stack[stackTop++] = root;
    while(stackTop) {
        struct TreeNode* temp = stack[--stackTop];
        struct TreeNode* tempNode = temp->right;
        temp->right = temp->left;
        temp->left = tempNode;
        if(temp->right)
            stack[stackTop++] = temp->right;
        if(temp->left)
            stack[stackTop++] = temp->left;
    }
    return root;
}

学习反思 

对二叉树有了更深刻的认知

101. 对称二叉树

题目链接/文章讲解/视频讲解:https://programmercarl.com/0101.%E5%AF%B9%E7%A7%B0%E4%BA%8C%E5%8F%89%E6%A0%91.html

思路

对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。

递归法

int isMirror(struct TreeNode* left, struct TreeNode* right) {
    if (left == NULL && right == NULL) return 1;
    if (left == NULL || right == NULL) return 0;
    return (left->val == right->val) &&
           isMirror(left->left, right->right) &&
           isMirror(left->right, right->left);
}

int isSymmetric(struct TreeNode* root) {
    return isMirror(root, root);
}

迭代

typedef struct {
    struct TreeNode** nodes; // 存储树节点的指针
    int front;
    int back;
    int capacity;
} Queue;
Queue* createQueue(int capacity) {
    Queue* queue = (Queue*)malloc(sizeof(Queue));
    queue->nodes = (struct TreeNode**)malloc(capacity * sizeof(struct TreeNode*));
    queue->front = 0;
    queue->back = 0;
    queue->capacity = capacity;
    return queue;
}
void enqueue(Queue* queue, struct TreeNode* node) {
    if (queue->back < queue->capacity) {
        queue->nodes[queue->back++] = node;
    }
}
struct TreeNode* dequeue(Queue* queue) {
    return queue->nodes[queue->front++];
}

int isEmpty(Queue* queue) {
    return queue->front == queue->back;
}
void freeQueue(Queue* queue) {
    free(queue->nodes);
    free(queue);
}
int isSymmetric(struct TreeNode* root) {
    if (root == NULL) return 1;

    Queue* queue = createQueue(2000);
    enqueue(queue, root->left);
    enqueue(queue, root->right);

    while (!isEmpty(queue)) {
        struct TreeNode* left = dequeue(queue);
        struct TreeNode* right = dequeue(queue);
        if (left == NULL && right == NULL) continue;
        if (left == NULL || right == NULL) return 0;
        if (left->val != right->val) return 0;
        enqueue(queue, left->left);
        enqueue(queue, right->right);
        enqueue(queue, left->right);
        enqueue(queue, right->left);
    }

    freeQueue(queue);
    return 1;
}

学习反思

对二叉树有了更深刻的认知。

104.二叉树的最大深度

题目链接/文章讲解/视频讲解: https://programmercarl.com/0104.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6.html

思路

本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)

而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。

 递归

int maxDepth(struct TreeNode* root){
    if(!root)
        return 0;
    int left = maxDepth(root->left);
    int right = maxDepth(root->right);
    int max = left > right ? left : right;
    return max + 1;
}

迭代

int maxDepth(struct TreeNode* root){
    if(!root)
        return 0;
    int depth = 0;
    struct TreeNode** queue = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 6000);
    int queueFront = 0;
    int queueEnd = 0;
    queue[queueEnd++] = root;
    int queueSize;
    while(queueSize = queueEnd - queueFront) {
        int i;
        for(i = 0; i < queueSize; i++) {
            struct TreeNode* tempNode = queue[queueFront + i];
            if(tempNode->left)
                queue[queueEnd++] = tempNode->left;
            if(tempNode->right)
                queue[queueEnd++] = tempNode->right;
        }
        queueFront += queueSize;
        depth++;
    }
    return depth;
}

学习反思

对二叉树有了更深刻的认知。

111.二叉树的最小深度

题目链接/文章讲解/视频讲解:https://programmercarl.com/0111.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E6%B7%B1%E5%BA%A6.html

思路

直觉上好像和求最大深度差不多,其实还是差不少的。

本题依然是前序遍历和后序遍历都可以,前序求的是深度,后序求的是高度。

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数后者节点数(取决于高度从0开始还是从1开始)

那么使用后序遍历,其实求的是根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离 也同样是最小深度。

递归法

int minDepth(struct TreeNode* root) {
    if (root == NULL) return 0;
    if (root->left == NULL) return minDepth(root->right) + 1;
    if (root->right == NULL) return minDepth(root->left) + 1;
    int leftDepth = minDepth(root->left);
    int rightDepth = minDepth(root->right);
    return (leftDepth < rightDepth ? leftDepth : rightDepth) + 1;
}

迭代法

typedef struct {
    struct TreeNode** nodes; 
    int front;
    int back;
    int capacity;
} Queue;
Queue* createQueue(int capacity) {
    Queue* queue = (Queue*)malloc(sizeof(Queue));
    queue->nodes = (struct TreeNode**)malloc(capacity * sizeof(struct TreeNode*));
    queue->front = 0;
    queue->back = 0;
    queue->capacity = capacity;
    return queue;
}
void enqueue(Queue* queue, struct TreeNode* node) {
    if (queue->back < queue->capacity) {
        queue->nodes[queue->back++] = node;
    }
}
struct TreeNode* dequeue(Queue* queue) {
    return queue->nodes[queue->front++];
}
int isEmpty(Queue* queue) {
    return queue->front == queue->back;
}
void freeQueue(Queue* queue) {
    free(queue->nodes);
    free(queue);
}
int minDepth(struct TreeNode* root) {
    if (root == NULL) return 0;

    Queue* queue = createQueue(1000);
    enqueue(queue, root);
    int depth = 0;
    while (!isEmpty(queue)) {
        int levelSize = queue->back - queue->front;
        depth++;
        for (int i = 0; i < levelSize; i++) {
            struct TreeNode* curr = dequeue(queue);
            if (curr->left == NULL && curr->right == NULL) {
                freeQueue(queue);
                return depth;
            }
            if (curr->left) enqueue(queue, curr->left);
            if (curr->right) enqueue(queue, curr->right);
        }
    }

    freeQueue(queue);
    return depth;
}

学习反思

对二叉树有了更深刻的认知。

总结

二叉树相对来说还是比较难,加油!!!

标签:right,TreeNode,struct,随想录,queue,二叉树,left,root,第十三天
From: https://blog.csdn.net/a6666999d/article/details/142884296

相关文章

  • 递归——二叉树中的深搜
    文章目录计算布尔二叉树的值求根节点到叶节点数字之和二叉树剪枝验证二叉搜索树二叉搜索树中第K小的元素二叉树的所有路径二叉树中的深搜有三种方法前序遍历根->左子树->右子树中序遍历左子树->根->右子树前序遍历左子树->右子树->根计算布尔二叉树的值......
  • 代码随想录训练营第五天|Leetcode.349,Leetcode.454,Leetcode19,Leetcode18
    一、哈希表和set和map和数组的关系 用哈希表,判断是否出现过。数值很大或者数值很分散时,不用数组,占用空间大,用set。set,multiset数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判......
  • 二叉树(上)
    目录1.树型结构(了解)1.1树形结构概念1.2树概念(重要)​编辑1.3树的表示形式(了解)1.4树的应用​编辑2.二叉树(重点)2.1概念2.2两种特殊的二叉树2.3二叉树的性质2.4二叉树的存储2.5二叉树的基本操作2.5.1前置说明1.树型结构(了解)1.1树形结构概念树......
  • 代码随想录训练营第60天|冗余连接
    108.冗余连接#include<iostream>#include<vector>usingnamespacestd;intn;//节点数量vector<int>father(1001,0);//按照节点大小范围定义数组//并查集初始化voidinit(){for(inti=0;i<=n;++i){father[i]=i;}}//并查集......
  • 代码随想录算法训练营day12|144.二叉树的前序遍历 94.二叉树的中序遍历 145.二叉
    学习资料:https://programmercarl.com/二叉树理论基础.html二叉树:满二叉树、完全二叉树、二叉搜索数、平衡二叉搜索树;链式存储、顺序存储;前序/中序/后序遍历递归法、迭代法,层序深度优先搜索dfs,广度优先搜索学习记录:144.二叉树的前序遍历(也要注重二叉数的输入方式;递归法比迭......
  • 代码随想录Day23 | LeetCode 455. 分发饼干、LeetCode 53. 最大子数组和、LeetCode 37
    LeetCode455.分发饼干贪心就是干classSolution:deffindContentChildren(self,g:List[int],s:List[int])->int:g.sort(reverse=True)s.sort(reverse=True)i=j=0res=0whilei<len(g)andj<len(......
  • 代码随想录算法训练营 | 完全背包,518. 零钱兑换 II,377. 组合总和 Ⅳ,70. 爬楼梯 (进阶)
    完全背包题目链接:完全背包文档讲解︰代码随想录(programmercarl.com)视频讲解︰完全背包日期:2024-10-11想法:dp数组设置思路跟01背包一样,不同在遍历上,完全背包遍历背包大小是从weight[i]开始的(背包空间小于weight[i]就没有意义,不用考虑,直接用之前的对应数值就行了),从前往后遍历就能......
  • 【hot100-java】二叉树的右视图
    二叉树篇tql /***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*TreeNode(intval){this.val=val;}*TreeNode(intval,TreeNodeleft,Tre......
  • 刷题计划 day12 二叉树(一)【定义】【递归遍历】【迭代遍历】
    ⚡刷题计划day12 二叉树(一)继续,这一小节主要是基础知识,但同样也是十分重要的,可以点个免费的赞哦~往期可看专栏,关注不迷路,您的支持是我的最大动力......
  • 01数组算法/代码随想录
    一、数组好久没写算法题,之前喜欢按着习惯选择刷题,很早以前就听说代码随想录,今天跟着代码随想录再过一遍算法1.1二分查找常见疑问middle一定是在[left,right]这个范围内标准代码不会越界,因为在elseif中出现越界后,下一次循环就不会通过左闭右闭区间代码示例public......