【代码随想录】【算法训练营】【第23天】 [669]修剪二叉搜索树 [108]将有序数组转换为二叉搜索树 [538]将二叉搜索树转换为累加树

前言

思路及算法思维,指路 代码随想录

题目来自 LeetCode

day 23,周四,坚持~

题目详情

[669] 修剪二叉搜索树

题目描述

669 修剪二叉搜索树

解题思路

前提:二叉搜索树

思路:根据二叉搜索树的有序性,可以删除不在区间的结点或结点范围。

重点:删除后根节点可能会发生变化。

代码实现

C语言
搜索二叉树 递归删除
c 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

struct TreeNode* trimBST(struct TreeNode* root, int low, int high) {
    // 判空
    if (root == NULL)
    {
        return root;
    }
    // 判断是否根节点结点
    if (root->val < low)
    {
        // 该结点及其左子树均要删除, 右子树需要递归删除
        root->right = trimBST(root->right, low, high);
        return root->right;
    }
    else if (root->val > high)
    {
        // 该结点及其右子树均要删除, 左子树需要递归删除
        root->left = trimBST(root->left, low, high);
        return root->left;
    }
    else
    {
        //根节点不修剪
        // 左子树
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);
    }
    return root;
}
二叉搜索树 迭代,移动根节点使其在范围内
c 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

struct TreeNode* trimBST(struct TreeNode* root, int low, int high) {
    // 判空
    if (root == NULL)
    {
        return root;
    }
    // 移动根节点结点,使其在[low, high]范围内
    while ((root) && ((root->val < low) || (root->val > high)))
    {
        if (root->val < low)
        {
            root = root->right;
        }
        else
        {
            root = root->left;
        }
    }
    struct TreeNode *cur = root;
    // 遍历左子树,删除小于low的元素
    while (cur)
    {
        // 移动左根节点结点,使其在[low, high]范围内
        while ((cur->left) && (cur->left->val < low))
        {
            cur->left = cur->left->right;
        }
        // 继续判断新左子树的左子树
        cur = cur->left;
    }
    // 遍历右子树,删除大于high的元素
    cur = root;
    while (cur)
    {
        // 移动右根节点结点,使其在[low, high]范围内
        while ((cur->right) && (cur->right->val > high))
        {
            cur->right = cur->right->left;
        }
        // 继续判断新右子树的右子树
        cur = cur->right;
    }
    return root;
}

[108] 将有序数组转换为二叉搜索树

题目描述

108 将有序数组转换为二叉搜索树

解题思路

前提:有序递增数组,转换为二叉搜索树

思路:确定根节点、左右子树的区间范围,递归遍历生成结点。

重点:升序数组与二叉搜索树的联系。

代码实现

C语言
递归
c 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {
    // 判空
    if (numsSize == 0)
    {
        return NULL;
    }
    // 不为空
    // 根节点
    int idx = numsSize / 2;
    struct TreeNode *root = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    root->val = nums[idx];
    root->left = sortedArrayToBST(nums, idx);
    root->right = sortedArrayToBST(nums + idx + 1, numsSize - idx - 1);
    return root;
}
迭代 3个队列存放左右子树临界位置及根节点
c 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {
    // 判空
    if (numsSize == 0)
    {
        return NULL;
    }
    // 不为空
    struct TreeNode *root = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    // 定义3个队列存放左边界、根节点、右边界的位置,左闭右闭
    struct TreeNode * rootQueue[10000];
    int leftQueue[10000];
    int rightQueue[10000];
    int idx = 0;
    // 队列初始化
    leftQueue[idx] = 0;
    rightQueue[idx] = numsSize - 1;
    rootQueue[idx] = root;
    idx++;
    while (idx)
    {
        struct TreeNode *cur = rootQueue[idx - 1];
        int leftLoc = leftQueue[idx - 1];
        int rightLoc = rightQueue[idx - 1];
        int rootLoc = leftLoc + (rightLoc - leftLoc) / 2;
        idx--;
        cur->val = nums[rootLoc];
        cur->left = NULL;
        cur->right = NULL;
        // 处理左区间
        if (leftLoc < rootLoc)
        {
            cur->left = (struct TreeNode *)malloc(sizeof(struct TreeNode));
            leftQueue[idx] = leftLoc;
            rightQueue[idx] = rootLoc - 1;
            rootQueue[idx] = cur->left;
            idx++;
        }
        // 处理右区间
        if (rightLoc > rootLoc)
        {
            cur->right = (struct TreeNode *)malloc(sizeof(struct TreeNode));
            leftQueue[idx] = rootLoc + 1;
            rightQueue[idx] = rightLoc;
            rootQueue[idx] = cur->right;
            idx++;
        }
    }
    return root;
}

[538] 将二叉搜索树转换为累加树

题目描述

538 将二叉搜索树转换为累加树

解题思路

前提:累加树,每个节点node新值>=原值之和,有点难理解什么是累加树,但是从例子中可以看书,就是该二叉搜索树中序遍历数组,从后往前相邻两值累加,覆盖原树的node值。

思路:反中序遍历,即右中左,处理node值大小。

重点:记录当前处理结点的上一节点,保留其值,用于相加。

代码实现

C语言
反中序 右中左 迭代
c 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* convertBST(struct TreeNode* root) {
    // 判空
    if (root == NULL)
    {
        return root;
    }
    // 不为空树
    struct TreeNode *stack[10000];
    int idx = 0;
    struct TreeNode *cur = root;
    int pre = 0;
    while ((idx) || (cur != NULL))
    {
        if (cur)
        {
            stack[idx++] = cur;
            // 右子树
            cur = cur->right;
        }
        else
        {
            // 中
            cur = stack[--idx];
            cur->val += pre;
            pre = cur->val;
            // 左子树
            cur = cur->left;
        }
    }
    return root;
}
反中序 右中左 递归
c 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

void traversal(struct TreeNode *root, int *pre)
{
    // 判空
    if (root == NULL)
    {
        return ;
    }
    // 右子树
    traversal(root->right, pre);
    // 中
    root->val += *pre;
    *pre = root->val;
    // 左子树
    traversal(root->left, pre);
    return ;
}

struct TreeNode* convertBST(struct TreeNode* root) {
    int pre = 0;
    traversal(root, &pre);
    return root;
}

今日收获

  1. 二叉搜索树的相关实现。
相关推荐
EterNity_TiMe_9 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
机器学习之心20 分钟前
一区北方苍鹰算法优化+创新改进Transformer!NGO-Transformer-LSTM多变量回归预测
算法·lstm·transformer·北方苍鹰算法优化·多变量回归预测·ngo-transformer
yyt_cdeyyds31 分钟前
FIFO和LRU算法实现操作系统中主存管理
算法
alphaTao1 小时前
LeetCode 每日一题 2024/11/18-2024/11/24
算法·leetcode
kitesxian1 小时前
Leetcode448. 找到所有数组中消失的数字(HOT100)+Leetcode139. 单词拆分(HOT100)
数据结构·算法·leetcode
VertexGeek2 小时前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
石小石Orz2 小时前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
jiao_mrswang3 小时前
leetcode-18-四数之和
算法·leetcode·职场和发展
qystca3 小时前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法
薯条不要番茄酱3 小时前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea