随想录二刷Day24——二叉树

很久没有刷算法题了,又荒废了,习惯还得保持啊,希望能坚持一天1~2道题。

文章目录

  • 二叉树
    • [32. 将有序数组转换为二叉搜索树](#32. 将有序数组转换为二叉搜索树)
    • [33. 把二叉搜索树转换为累加树](#33. 把二叉搜索树转换为累加树)

二叉树

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

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

思路:

有序数组要生成普通二叉树,只需要简单的一长溜就可以了。所以题目要求生成平衡二叉树。要平衡,就要左右子树的节点数最多相差1,自然而然,从数组的中间划分为左右子树,就显得很容易。

方法1: 递归法

递归的思路很清晰,对左右区间递归构造二叉搜索树即可。

cpp 复制代码
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        TreeNode *root = Transfer(nums, 0, nums.size() - 1);
        return root;
    }

private:
    TreeNode* Transfer(vector<int>& nums, int left, int right) {
        if (left > right) return nullptr;
        int mid = left + ((right - left)>>1);
        TreeNode *root = new TreeNode(nums[mid]);
        root->left = Transfer(nums, left, mid - 1);
        root->right = Transfer(nums, mid + 1, right);
        return root;
    }
};

方法2:迭代法

同递归法的思路,只不过要利用队列存储当前处理区间的当前处理节点。

cpp 复制代码
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        if (nums.size() == 0) return nullptr;

        TreeNode *root = new TreeNode(0);
        queue<TreeNode *> nodeQue; // 栈顶是当前处理到的节点
        queue<int> leftQue; // 存当前处理区间的左边界
        queue<int> rightQue; // 存当前处理区间的有边界
        nodeQue.push(root); // 初始处理节点是根节点
        leftQue.push(0); // 初始左边界是 0
        rightQue.push(nums.size() - 1); // 初始右边界

        while (!nodeQue.empty()) {
            TreeNode *curNode = nodeQue.front(); nodeQue.pop();
            int left = leftQue.front(); leftQue.pop();
            int right = rightQue.front(); rightQue.pop();
            int mid = left + ((right - left) >> 1);

            curNode->val = nums[mid];
            
            // 先处理左区间
            if (left < mid) {
                curNode->left = new TreeNode(0);
                nodeQue.push(curNode->left);
                leftQue.push(left);
                rightQue.push(mid - 1);
            }

            // 再处理右区间
            if (right > mid) {
                curNode->right = new TreeNode(0);
                nodeQue.push(curNode->right);
                leftQue.push(mid + 1);
                rightQue.push(right);
            }
        }
        return root;
    }
};

33. 把二叉搜索树转换为累加树

538. 把二叉搜索树转换为累加树

思路:

二叉搜索树变成累加树,题干说的听抽象的,看不太懂,观察样例可以看出,根节点值是自身和右子树的累加和,左子节点是自身和根节点新值的累加。其实就是得到后续遍历的结果,再从左向右依次累加。

在遍历过程中处理,需要记录一个 pre 值,表示前一个节点的值,方便做累加。

方法1:递归法

cpp 复制代码
class Solution {
public:
    TreeNode* convertBST(TreeNode* root) {
        pre = 0;
        Transfer(root);
        return root;
    }

private:
    int pre = 0;
    void Transfer(TreeNode* root) {
        if (root == nullptr) return ;
        Transfer(root->right); // 右

        // 中
        root->val += pre;
        pre = root->val;
        
        Transfer(root->left); // 左
    }
};

方法2:迭代法

典型的后续遍历模板

cpp 复制代码
class Solution {
public:
    TreeNode* convertBST(TreeNode* root) {
        Transfer(root);
        return root;
    }

private:
    void Transfer(TreeNode* root) {
        int pre = 0;
        stack<TreeNode *> stk;
        TreeNode *cur = root;

        while (cur != nullptr || !stk.empty()) {
            if (cur != nullptr) { // 右
                stk.push(cur);
                cur = cur->right;
            } else {
                // 中
                cur = stk.top(); stk.pop();
                cur->val += pre;
                pre = cur->val;
                cur = cur->left; // 左
            }
        }
    }
};
相关推荐
侯小啾3 小时前
【03】C语言 强制类型转换 与 进制转换
c语言·数据结构·算法
Xの哲學3 小时前
Linux NAPI 架构详解
linux·网络·算法·架构·边缘计算
京东零售技术6 小时前
扛起技术大梁的零售校招生们 | 1024技术人特别篇
算法
爱coding的橙子7 小时前
每日算法刷题Day78:10.23:leetcode 一般树7道题,用时1h30min
算法·leetcode·深度优先
Swift社区7 小时前
LeetCode 403 - 青蛙过河
算法·leetcode·职场和发展
地平线开发者7 小时前
三种 Badcase 精度验证方案详解与 hbm_infer 部署实录
算法·自动驾驶
papership7 小时前
【入门级-算法-5、数值处理算法:高精度的减法】
算法·1024程序员节
lingran__7 小时前
算法沉淀第十天(牛客2025秋季算法编程训练联赛2-基础组 和 奇怪的电梯)
c++·算法
DuHz7 小时前
基于MIMO FMCW雷达的二维角度分析多径抑制技术——论文阅读
论文阅读·物联网·算法·信息与通信·毫米波雷达
Dragon_D.8 小时前
排序算法大全——插入排序
算法·排序算法·c·学习方法