二叉树简单题

二叉树简单题

2331. 计算布尔二叉树的值

bool evaluateTree(struct TreeNode *root) {
    // 递归出口
    if (root == NULL) return root;
    if (root->left == NULL && root->right == NULL)return root->val;

    // 递归体
    bool left = evaluateTree(root->left);
    bool right = evaluateTree(root->right);
    // 或运算
    if (root->val == 2) return left || right;
    // 与运算
    return left && right;
}

938. 二叉搜索树的范围和

// 递归
int rangeSumBST(struct TreeNode *root, int low, int high) {
    // 递归出口
    if (root == nullptr) return 0;

    // 递归体
    if (root->val < low) return rangeSumBST(root->right, low, high);
    if (root->val > high) return rangeSumBST(root->left, low, high);
    return rangeSumBST(root->right, low, high) + rangeSumBST(root->left, low, high) + root->val;
}
// 迭代
const int size = 10002;

int judge(int k, int low, int high) {
    if (k < low || k > high)
        return 0;
    return k;
}

int rangeSumBST(struct TreeNode *root, int low, int high) {
    if (root == NULL) return 0;
    // 循环队列(顺序存储)
    struct TreeNode *array[size];
    int front = 0, rear = 0;
    array[rear++] = root;
    int res = 0;

    while (front != rear) {
        int count = (rear - front + size) % size;
        while (count-- > 0) {
            struct TreeNode *node = array[(front++) % size];
            res += judge(node->val, low, high);
            if (node->val >= low && node->val <= high) {
                if (node->left != NULL) array[(rear++) % size] = node->left;
                if (node->right != NULL) array[(rear++) % size] = node->right;
            } else if (node->val > high && node->left != NULL) {
                array[(rear++) % size] = node->left;
            } else if (node->val < low && node->right != NULL) {
                array[(rear++) % size] = node->right;
            }
        }
    }
    return res;
}
// 迭代
int rangeSumBST(struct TreeNode *root, int low, int high) {
    if (root == NULL) return 0;
    // 栈
    struct TreeNode *array[10002];
    int res = 0;
    int top = 0;

    while (top != 0 || root != NULL) {
        while (root != NULL) {
            // 当前节点可以入栈,因为右子树中可能有符合条件的
            array[top++] = root;
            printf("%d入栈 ", root->val);
            if (root->left == NULL || (root->val <= low)) 
                // 当前节点的左子树没必要入栈
                break;
            else
                root = root->left;
        }

        root = array[--top];
        printf("%d出栈 ", root->val);
        res += judge(root->val, low, high);
        if (root->right == NULL || (root->val >= high)) {
            // 当前节点的值已经超范围了,没必要往右子树找
            root = NULL;
        } else {
            root = root->right;
        }
    }

    return res;
}

222. 完全二叉树的节点个数

int countLever(struct TreeNode *root) {
    int res = 0;
    while (root != NULL) {
        res++;
        root = root->left;
    }
    return res;
}

// 完全二叉树的节点个数
int countNodes(struct TreeNode *root) {
    if (root == NULL) return 0;

    int leftLever = countLever(root->left);
    int rightLever = countLever(root->right);

    if (leftLever == rightLever) 
        // 此时左子树必为满二叉树,直接计算出左子树节点数并加上; 再加上右子树的节点数
        return (1 << leftLever) - 1 + countNodes(root->right) + 1; // 1 << leftLever为2的leftLever次方
    else 
        // 此时右子树必为满二叉树,比左子树高度少一
        return (1 << rightLever) - 1 + countNodes(root->left) + 1;
}

226. 翻转二叉树

struct TreeNode *invertTree(struct TreeNode *root) {
    if (root == NULL) return root;

    struct TreeNode *left = invertTree(root->right);
    struct TreeNode *right = invertTree(root->left);
    root->left = left;
    root->right = right;
    return root;
}

617. 合并二叉树

struct TreeNode *mergeTrees(struct TreeNode *root1, struct TreeNode *root2) {
    if (root1 == NULL) return root2;
    if (root2 == NULL) return root1;

    root1->val += root2->val;
    root1->left = mergeTrees(root1->left, root2->left);
    root1->right = mergeTrees(root1->right, root2->right);

    return root1;
}

LCR 175. 计算二叉树的深度

// 递归
int calculateDepth(struct TreeNode *root) {
    if (root == NULL) return 0;
    int left = calculateDepth(root->left);
    int right = calculateDepth(root->right);
    return (left > right ? left : right) + 1;
}
// 层序遍历
int calculateDepth(struct TreeNode *root) {
    if (root == NULL) return 0;
    int depth = 0;
    const int size = 5002;
    // 循环队列
    struct TreeNode *queue[size];
    int front = 0, rear = 0;
    queue[rear++] = root;

    while (front != rear) {
        int count = (rear - front + size) % size;
        // 一层加一次
        depth++;
        while (count-- > 0) {
            struct TreeNode *node = queue[(front++) % size];
            if (node->left != NULL) queue[(rear++) % size] = node->left;
            if (node->right != NULL) queue[(rear++) % size] = node->right;
        }
    }
    return depth;
}

面试题 04.02. 最小高度树

// 给定一个有序整数数组,元素各不相同且按升序排列,编写一个算法,创建一棵高度最小的二叉搜索树
// 递归生成平衡二叉树
struct TreeNode *generate(int *nums, int left, int right) {
    if (left > right) return NULL;
    // 向下取整的中间元素
    int mid = (right - left) / 2 + left;
    
    struct TreeNode *node = (struct TreeNode *) malloc(sizeof(struct TreeNode));
    node->val = nums[mid];
    node->left = generate(nums, left, mid - 1);
    node->right = generate(nums, mid + 1, right);
    return node;
}

struct TreeNode *sortedArrayToBST(int *nums, int numsSize) {
    return generate(nums, 0, numsSize - 1);
}

700. 二叉搜索树中的搜索

struct TreeNode *searchBST(struct TreeNode *root, int val) {
    if (root == NULL) return root;
    if (root->val == val) return root;
    return (root->val > val) ? searchBST(root->left, val) : searchBST(root->right, val);
}

LCR 174. 寻找二叉搜索树中的目标节点

// 找第cnt大的元素
int count = 0;
int res = -1;

void inorder(struct TreeNode *root){
    if (root == NULL || count < 0) return;

    // 按右中左的顺序
    inorder(root->right);
    count--;
    if (count == 0) {
        res = root->val;
        return;
    }
    inorder(root->left);
}


int findTargetNode(struct TreeNode *root, int cnt) {
    count = cnt;
    inorder(root);
    return res;
}

1022. 从根到叶的二进制数之和

int sum;
// 先序遍历
void preOrder(struct TreeNode *root, int temp) {
    if (root == NULL) return;
    // 更新当前值
    temp = (temp << 1) + node->val;
    // 到叶节点才输出
    if (root->left == NULL && root->right == NULL) {
        sum += temp;
        return;
    }
    preOrder(root->left, temp);
    preOrder(root->right, temp);
}

int sumRootToLeaf(struct TreeNode *root) {
    sum = 0;
    preOrder(root, 0);
    return sum;
}
int preorder(struct TreeNode *node, int temp) {
    if (node == NULL) return 0;
    // 更新当前值
    temp = (temp << 1) + node->val;
    // 到叶节点才输出
    if (node->left == NULL && node->right == NULL) return temp;
    return preorder(node->left, temp) + preorder(node->right, temp);
}

int sumRootToLeaf(struct TreeNode *root) {
    return preorder(root, 0);
}

897. 递增顺序搜索树

struct TreeNode *pre;
struct TreeNode *newRoot;

void inorder(struct TreeNode *root) {
    if (root == NULL) return;

    inorder(root->left);
    root->left = NULL; // 下放到if里面pre->left = NULL时,如果倒数第二个节点是最后一个节点的左孩子,会在最后两个节点死循环

    if (newRoot == NULL) {
        // 最左下角节点
        newRoot = root;
    } else {
        // 后续所有节点
        pre->right = root;
    }
    pre = root;

    inorder(root->right);
}

struct TreeNode *increasingBST(struct TreeNode *root) {
    pre = NULL;
    newRoot = NULL;
    inorder(root);
    return newRoot;
}
struct TreeNode *pre;
struct TreeNode *newRoot;

void inorder(struct TreeNode *root) {
    if (root == NULL) return;

    inorder(root->left);

    if (newRoot == NULL) {
        // 最左下角节点
        newRoot = root;
    } else {
        // 后续所有节点
        pre->left = NULL;
        pre->right = root;
    }
    pre = root;

    inorder(root->right);
}

struct TreeNode *increasingBST(struct TreeNode *root) {
    pre = NULL;
    newRoot = NULL;
    inorder(root);
    // 单独处理最后一个节点,避免死循环
    pre->left = NULL;
    return newRoot;
}

257. 二叉树的所有路径

// todo

637. 二叉树的层平均值

// 层序遍历
double *averageOfLevels(struct TreeNode *root, int *returnSize) {
    const int size = 5001;
    struct TreeNode *array[size];
    int front = 0, rear = 0;
    array[rear++] = root;
    double *res = (double*)malloc(sizeof(double) * 10000);
    *returnSize = 0;

    while (front != rear) {
        int count = (rear - front + size) % size;
        int k = count;
        double sum = 0.0;
        while (k-- > 0) {
            root = array[(front++) % size];
            sum += root->val;
            if (root->left != NULL) array[(rear++) % size] = root->left;
            if (root->right != NULL) array[(rear++) % size] = root->right;
        }
        res[(*returnSize)++] = sum / count;
    }

    return res;
}


@[runtime error: load of null pointer of type ‘_Bool’ [Serializer.c]错误提示

c语言编写的程序在使用内存时一般分为三个段:正文段,数据堆段,数据栈段

正文段:存储全局变量和二进制代码
数据栈段:存储临时使用的局部变量
数据堆段:存储动态分配的存储区(malloc)

当返回值为指针,在函数退出时,局部变量的存储空间会被销毁,此时再去访问该地址就访问不到

解决办法:
1、使用malloc动态分配存储空间
2、使用static修饰该变量
3、使用全局变量存储
void preorder(struct TreeNode *root, double *sum, int *count, int depth) {
    if (root == NULL) return;

    // 记录深度
    depth++;
    sum[depth] += root->val;
    count[depth]++;

    preorder(root->left, sum, count, depth);
    preorder(root->right, sum, count, depth);
}

double *averageOfLevels(struct TreeNode *root, int *returnSize) {
    double *res = (double *) malloc(sizeof(double) * 10001);
    *returnSize = 0;

    double sum[10001];
    int count[10001];
    for (int i = 0; i < 10001; ++i) {
        sum[i] = 0;
        count[i] = 0;
    }

    preorder(root, sum, count, 0);

    int i = 1;
    while (count[i] != 0) {
        res[(*returnSize)++] = sum[i] / count[i];
        i++;
    }

    return res;
}

LCR 194. 二叉树的最近公共祖先

// 前提:节点的值唯一,p、q都在二叉树中
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q){
    if(root == NULL)
        // 如果树为空,直接返回null
        return NULL;
    if(root == p || root == q)
        // 如果p和q中有等于root的,那么它们的最近公共祖先即为root(一个节点也可以是它自己的祖先)
        return root;
    // 递归遍历左子树,只要在左子树中找到了p或q,则先找到谁就返回谁
    struct TreeNode *left = lowestCommonAncestor(root->left, p, q);
    // 递归遍历右子树,只要在右子树中找到了p或q,则先找到谁就返回谁
    struct TreeNode *right = lowestCommonAncestor(root->right, p, q);
    if(left == NULL)
        // 如果在左子树中p和q都找不到,则 p和 q一定都在右子树中,右子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)
        return right;
    else if(right == NULL)
        // 否则,如果left不为空,在左子树中有找到节点(p或q),这时候要再判断一下右子树中的情况。如果在右子树中,p和q都找不到,则p和q一定都在左子树中,左子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)
        return left;
    else
        //否则,当left和right均不为空时,说明p、q节点分别在 root异侧, 最近公共祖先即为 root
        return root;
}
// 方法二:记录跟节点到p、q的路径。从p、q往上找到第一个公共的节点

563. 二叉树的坡度

int sum;

// 返回树的所有节点值之和
int count(struct TreeNode *root) {
    if (root == NULL) return 0;
    int left = count(root->left);
    int right = count(root->right);

    sum += left > right ? left - right : right - left;
    return left + right + root->val;
}

int findTilt(struct TreeNode *root) {
    if (root == NULL)return 0;
    sum = 0;
    count(root);
    return sum;
}

872. 叶子相似的树

bool res;

// 先序遍历,叶节点入栈
void preorder1(struct TreeNode *root, int *array, int *size) {
    if (root == NULL) return;
    if (root->left == NULL && root->right == NULL)
        array[(*size)++] = root->val;
    preorder1(root->left, array, size);
    preorder1(root->right, array, size);
}

// 根右左的顺序遍历
void preorder2(struct TreeNode *root, int *array, int *size) {
    if (root == NULL) return;
    if (root->left == NULL && root->right == NULL) {
        (*size)--;
        // 判断出栈元素是否和当前值一样(倒过来比较两个序列)
        if ((*size >= 0 && array[*size] != root->val) || *size < 0) res = false;
        return;
    }
    preorder2(root->right, array, size);
    preorder2(root->left, array, size);
}

bool leafSimilar(struct TreeNode *root1, struct TreeNode *root2) {
    int array[200];
    int size = 0;
    res = true;

    preorder1(root1, array, &size);
    preorder2(root2, array, &size);
    return res && (size == 0);
}

653. 两数之和 IV - 输入二叉搜索树

// 散列
bool dfs(struct TreeNode *root, bool *hashMap, int k) {
    if (root == NULL) return false;

    bool left = dfs(root->left, hashMap, k);
    // 把数值移到正数范围
    if (hashMap[k - root->val + 10000]) return true;
    hashMap[root->val + 10000] = true;
    bool right = dfs(root->right, hashMap, k);
    return left || right;
}

bool findTarget(struct TreeNode *root, int k) {
    // calloc() 函数会将分配的内存全部初始化为零
    bool *hashMap = (bool*)calloc(200001, sizeof(bool));
    return dfs(root, hashMap, k);
}
// 中序遍历放入一维数组,再用双指针
int *array;
int *myIndex;

void inorder(struct TreeNode *root) {
    if (root == NULL)return;
    inorder(root->left);
    array[(*myIndex)++] = root->val;
    inorder(root->right);
}

bool findTarget(struct TreeNode *root, int k) {
    array = (int *) calloc(10000, sizeof(int));
    int temp = 0;
    myIndex = &temp;

    inorder(root);

    int left = 0;
    int right = *myIndex - 1;
    while (left < right) {
        if (array[left] + array[right] == k)
            return true;
        else if (array[left] + array[right] < k)
            left++;
        else
            right--;
    }
    return false;
}

530. 二叉搜索树的最小绝对差

int pre;
int res;

void inorder(struct TreeNode *root) {
    if (root == NULL)return;
    inorder(root->left);
    if (pre >= 0 && root->val - pre < res)
        res = root->val - pre;
    pre = root->val;
    inorder(root->right);
}

int getMinimumDifference(struct TreeNode *root) {
    pre = -1;
    res = 0x7fffffff;
    inorder(root);
    return res;
}

LCR 059. 数据流中的第 K 大元素


// todo

606. 根据二叉树创建字符串

char *res;

void preorder(struct TreeNode *root) {
    if (root == NULL) return;

    sprintf(res + strlen(res), "%d", root->val);
    if (root->left == NULL && root->right == NULL) {
    } else if (root->right == NULL) {
        sprintf(res + strlen(res), "(");
        preorder(root->left);
        sprintf(res + strlen(res), ")");
    } else if (root->left == NULL) {
        sprintf(res + strlen(res), "()(");
        preorder(root->right);
        sprintf(res + strlen(res), ")");
    } else {
        sprintf(res + strlen(res), "(");
        preorder(root->left);
        sprintf(res + strlen(res), ")(");
        preorder(root->right);
        sprintf(res + strlen(res), ")");
    }
}


// 用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。空节点使用一对空括号对 "()" 表示
char *tree2str(struct TreeNode *root) {
    res = (char *) malloc(sizeof(char) * 100000);
    res[0] = '\0';
    preorder(root);
    return res;
}

100. 相同的树

bool isSameTree(struct TreeNode *p, struct TreeNode *q) {
    if (p == NULL && q == NULL) return true;
    if (p == NULL || q == NULL) return false;
    if (p->val != q->val)return false;
    return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}

面试题 04.04. 检查平衡性

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

// 自上而下
bool isBalanced(struct TreeNode *root) {
    if (root == NULL) return true;
    // 有重复的高度计算
    int gap = depth(root->left) - depth(root->right);
    if (gap < -1 || gap > 1) return false;
    return isBalanced(root->left) && isBalanced(root->right);
}
// 自下而上,先判断子树是否平衡
int height(struct TreeNode *root) {
    if (root == NULL) return 0;

    int left = height(root->left);
    // 左子树不平衡
    if (left == -1) return -1;
    int right = height(root->right);
    // 右子树不平衡
    if (right == -1) return -1;
    int gap = left - right;
    // 当前节点不平衡
    if (gap < -1 || gap > 1) return -1;
    return (left > right ? left : right) + 1;
}

bool isBalanced(struct TreeNode *root) {
    return height(root) >= 0;
}

101. 对称二叉树

// 递归
bool dfs(struct TreeNode *L, struct TreeNode *R) {
    if (L == NULL && R == NULL) return true;
    if (L == NULL || R == NULL || L->val != R->val) return false;
    return dfs(L->left, R->right) && dfs(L->right, R->left);
}

bool isSymmetric(struct TreeNode *root) {
    if (root == NULL) return true;
    return dfs(root->left, root->right);
}
// 迭代
bool isSymmetric(struct TreeNode *root) {
    if (root == NULL) return true;
    if (root->left == NULL && root->right == NULL) return true;
    if (root->left == NULL || root->right == NULL || root->left->val != root->right->val) return false;

    const int size = 1001;
    struct TreeNode *queue[size];
    int front = 0, rear = 0;
    // 左右孩子入队
    queue[rear++] = root->left;
    queue[rear++] = root->right;

    while (rear != front) {
        struct TreeNode *L = queue[(front++) % size];
        struct TreeNode *R = queue[(front++) % size];
        if (L == NULL && R == NULL) return true;
        if ((L == NULL || R == NULL)
            || (L->val != R->val)
            || (L->left == NULL && R->right != NULL)
            || (L->right == NULL && R->left != NULL)
            || (L->right == NULL && R->left != NULL)
            || (L->left == NULL && R->right != NULL))
            return false;
        if (L->left != NULL) {
            queue[(rear++) % size] = L->left;
            queue[(rear++) % size] = R->right;
        }
        if (L->right != NULL) {
            queue[(rear++) % size] = L->right;
            queue[(rear++) % size] = R->left;
        }
    }
    return true;
}

543. 二叉树的直径

int res;
// 求树高的同时记录最远距离
int height(struct TreeNode *root) {
    if (root == nullptr)return 0;
    int left = height(root->left);
    int right = height(root->right);
    if (left + right > res) res = left + right;
    return (left > right ? left : right) + 1;
}

int diameterOfBinaryTree(struct TreeNode *root) {
    res = 0;
    height(root);
    return res;
}

993. 二叉树的堂兄弟节点

// 层序遍历
// x,y必须出现在同一层,且不能是同一个父节点下的
bool isCousins(struct TreeNode *root, int x, int y) {
    const int size = 101;
    struct TreeNode *queue[size];
    int front = 0, rear = 0;
    queue[rear++] = root;

    while (front != rear) {
        int count = (rear - front + size) % size;
        // temp=2时,说明都出现在同一层了,且不是同一个父节点
        int temp = 0;
        // 遍历同一层的节点
        while (count-- > 0) {
            root = queue[(front++) % size];
            if (root == NULL || (root->left == NULL && root->right == NULL)) continue;
            // 同一节点的左右孩子
            if (root->left != NULL && root->right != NULL) {
                if ((root->left->val == x && root->right->val == y)
                    || (root->left->val == y && root->right->val == x))
                    return false;
            }
            // 左右节点只出现(不会是同一节点的左右孩子
            if (root->left != NULL && (root->left->val == x || root->left->val == y))temp++;
            if (root->right != NULL && (root->right->val == x || root->right->val == y))temp++;

            queue[(rear++) % size] = root->left;
            queue[(rear++) % size] = root->right;
        }
        if (temp == 2)return true;
    }
    return false;
}
struct TreeNode *parentX;
struct TreeNode *parentY;
int depthX;
int depthY;

// 记录各自的父节点和所处深度
void dfs(struct TreeNode *root, int x, int y, int depth) {
    if (root == NULL || (root->left == NULL && root->right == NULL)) return;
    depth++;
    // 是同一父节点,不符合条件
    if (root->left != NULL && root->right != NULL) {
        if ((root->left->val == x && root->right->val == y)
            || (root->left->val == y && root->right->val == x)) {
            parentX = root;
            parentY = root;
            return;
        }
    }
    if (root->left != NULL) {
        if (root->left->val == x) {
            parentX = root;
            depthX = depth;
        }
        if (root->left->val == y) {
            parentY = root;
            depthY = depth;
        }
    }
    if (root->right != NULL) {
        if (root->right->val == x) {
            parentX = root;
            depthX = depth;
        }
        if (root->right->val == y) {
            parentY = root;
            depthY = depth;
        }
    }
    dfs(root->left, x, y, depth);
    dfs(root->right, x, y, depth);
}

bool isCousins(struct TreeNode *root, int x, int y) {
    parentX = NULL;
    parentY = NULL;
    depthX = 0;
    depthY = 0;
    dfs(root, x, y, 0);
    printf("%d %d", depthX, depthY  );
    return (depthX == depthY) && (parentX != parentY);
}

501. 二叉搜索树中的众数

int curCount;
int maxCount;
int cur;
int *res;
// 中序
void inorder(struct TreeNode *root, int *returnSize) {
    if (root == NULL) return;
    
    inorder(root->left, returnSize);

    if (cur == root->val) {
        curCount++;
    } else {
        cur = root->val;
        curCount = 1;
    }
    if (curCount == maxCount) {
        res[(*returnSize)++] = cur;
    }
    if (curCount > maxCount) {
        maxCount = curCount;
        *returnSize = 0;
        res[(*returnSize)++] = cur;
    }

    inorder(root->right, returnSize);
}

int *findMode(struct TreeNode *root, int *returnSize) {
    res = (int *) malloc(sizeof(int) * 10000);
    curCount = 0;
    maxCount = 0;
    *returnSize = 0;
    cur = root->val;

    inorder(root, returnSize);

    return res;
}

112. 路径总和

// 自上而下
bool dfs(struct TreeNode *root, int tempSum, int targetSum) {
    if (root == NULL) return false;
    tempSum += root->val;
    if ((root->left == NULL && root->right == NULL) && (tempSum == targetSum))return true;
    return dfs(root->left, tempSum, targetSum) || dfs(root->right, tempSum, targetSum);
}

bool hasPathSum(struct TreeNode *root, int targetSum) {
    if (root == NULL) return false;
    return dfs(root, 0, targetSum);
}

// 把根节点到当前节点的权值和放到sum中
struct Node {
    struct TreeNode *node;
    int sum;
};

bool hasPathSum(struct TreeNode *root, int targetSum) {
    if (root == NULL) return false;
    const int size = 2002;
    int front = 0;
    int rear = 0;
    struct Node *queue = (struct Node *) malloc(sizeof(struct Node) * size);
    queue[rear++] = (struct Node) {root, root->val};

    while (front != rear) {
        struct Node node = queue[(front++) % size];
        if (node.node->left == NULL && node.node->right == NULL && node.sum == targetSum)
            return true;
        if (node.node->left != NULL)
            queue[(rear++) % size] = (struct Node) {node.node->left, node.sum + node.node->left->val};
        if (node.node->right != NULL)
            queue[(rear++) % size] = (struct Node) {node.node->right, node.sum + node.node->right->val};
    }
    return false;
}

111. 二叉树的最小深度

// 层序
int minDepth(struct TreeNode *root) {
    if (root == NULL) return 0;
    const int size = 50002;
    struct TreeNode *queue[size];
    int front = 0;
    int rear = 0;
    int depth = 0;
    queue[rear++] = root;

    while (front != rear) {
        int count = (rear - front + size) % size;
        depth++;
        while (count-- > 0) {
            struct TreeNode *node = queue[(front++) % size];
            if (node->left == NULL && node->right == NULL)
                return depth;
            if (node->left != NULL)queue[(rear++) % size] = node->left;
            if (node->right != NULL) queue[(rear++) % size] = node->right;
        }
    }

    return depth;
}
// 记录深度
void dfs(struct TreeNode *node, int *minDepth, int currentDepth) {
    if (node == NULL) return;
    currentDepth++;
    if (node->left == NULL && node->right == NULL && currentDepth < *minDepth)
        *minDepth = currentDepth;
    dfs(node->left, minDepth, currentDepth);
    dfs(node->right, minDepth, currentDepth);
}

int minDepth(struct TreeNode *root) {
    if (root == NULL) return 0;
    int *minDepth = (int *) malloc(sizeof(int));
    *minDepth = 100000;

    dfs(root, minDepth, 0);
    return *minDepth;
}

671. 二叉树中第二小的节点

// 迭代
int findSecondMinimumValue(struct TreeNode *root) {
    const int size = 14;
    struct TreeNode *queue[size];
    int front = 0, rear = 0;
    queue[rear++] = root;
    int min = root->val;
    int res = -1;

    while (front != rear) {
        int count = (rear - front + size) % size;
        while (count-- > 0) {
            root = queue[(front++) % size];
            if (min != root->val) {
                if (res == -1 || root->val < res) {
                    res = root->val;
                }
            }
            // 剪枝
            if (root->left != NULL) {
                if (res != -1 && root->left->val > res) continue;
                queue[(rear++) % size] = root->left;
            }
            if (root->right != NULL) {
                if (res != -1 && root->right->val > res) continue;
                queue[(rear++) % size] = root->right;
            }
        }
    }
    return res;
}
int min;
int res;

// 递归
void dfs(struct TreeNode *root) {
    if (root == NULL) return;
    if (root->val != min)
        if (res == -1 || root->val < res)
            res = root->val;
    // 剪枝
    if (root->left != NULL && (res == -1 || root->left->val <= res))
        dfs(root->left);
    if (root->right != NULL && (res == -1 || root->right->val <= res))
        dfs(root->right);
}

int findSecondMinimumValue(struct TreeNode *root) {
    min = root->val;
    res = -1;
    dfs(root);
    return res;
}

572. 另一棵树的子树

// 判断两个树是否一样
bool isSame(struct TreeNode *r1, struct TreeNode *r2) {
    if (r1 == nullptr && r2 == nullptr) return true;
    if (r1 == nullptr || r2 == nullptr || r1->val != r2->val) return false;
    return isSame(r1->left, r2->left) && isSame(r1->right, r2->right);
}

// 暴力匹配
bool isSubtree(struct TreeNode *root, struct TreeNode *subRoot) {
    if (root == nullptr) return false;
    if (isSame(root, subRoot)) return true;
    return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
// todo
// n+1个空链域上补成空节点,深度优先遍历序列上做串匹配
// todo
// 散列, 把二叉树映射成一个数
posted @ 2023-12-31 02:13  n1ce2cv  阅读(13)  评论(0编辑  收藏  举报