当前位置:首页 > 力扣 > 力扣面试04.09题解析:生成二叉搜索树的所有序列

力扣面试04.09题解析:生成二叉搜索树的所有序列

23小时前

力扣面试04.09题解析:生成二叉搜索树的所有序列 力扣面试题 二叉搜索树 回溯算法 队列优化 二叉树 力扣题解 队列 递归 第1张

一、题目解读

力扣面试04.09题要求生成一棵给定二叉搜索树(BST)的所有可能序列。由于BST中序遍历结果唯一,但节点插入顺序不同可能导致不同树结构,因此需通过深度遍历所有节点组合,输出所有合法的BST序列。题目难点在于如何高效且无重复地生成所有序列,并确保每个序列对应有效的BST结构。

二、解题思路

核心思路采用回溯算法 + 队列维护候选节点:

1. 队列初始化:将根节点入队,作为初始候选节点集。

2. 递归回溯:每次从队列头部取出节点,记录其值,并递归处理其左右子

3. 子节点入队:若当前节点有左/右子节点,将其加入队列末尾,扩展候选集。

4. 回溯撤销:递归结束后,需回溯撤销子节点入队操作,恢复当前节点状态,继续遍历其他路径。

5. 结果收集:当队列为空时,当前路径代表一棵完整BST的序列,加入结果集。

三、解题步骤

1. 初始化:若根节点为空,直接返回空结果集。

2. 创建队列:将根节点加入候选队列。

3. 主循环:

○ 循环直至队列为空,每次处理一个节点:

    取出当前节点,记录值到路径。

    若存在左/右子节点,分别入队(扩展搜索空间)。

    递归调用 backtrack(),生成子树序列。

    回溯时弹出子节点,恢复队列状态(避免重复)。

○ 最终路径加入结果集。

4. 返回所有序列:完成所有路径搜索后,返回结果集。

四、代码与注释

class Solution {
public:
    vector<vector<int>> BSTSequences(TreeNode* root) {
        if (!root) return {{}};  // 空树特判
        vector<vector<int>> res;  // 结果集
        vector<int> path;         // 当前路径
        deque<TreeNode*> candidates;  // 候选节点队列
        candidates.push_back(root);  // 根节点入队

        backtrack(candidates, path, res);  // 启动回溯
        return res;
    }

    void backtrack(deque<TreeNode*>& candidates, vector<int>& path, vector<vector<int>>& res) {
        if (candidates.empty()) {  // 队列为空,路径完整
            res.push_back(path);   // 加入结果集
            return;
        }

        int size = candidates.size();  // 记录当前队列长度
        for (int i = 0; i < size; ++i) {
            TreeNode* curr = candidates.front();  // 取出当前节点
            candidates.pop_front();              // 从队列移除

            path.push_back(curr->val);            // 记录节点值

            // 将子节点加入候选集(扩展搜索空间)
            if (curr->left)  candidates.push_back(curr->left);
            if (curr->right) candidates.push_back(curr->right);

            backtrack(candidates, path, res);  // 递归生成子树序列

            // 回溯:撤销子节点入队,恢复状态
            if (curr->right) candidates.pop_back();
            if (curr->left)  candidates.pop_back();
            candidates.push_back(curr);         // 回溯至父节点
            path.pop_back();                    // 撤销路径值
        }
    }
};

注释说明:

● 使用 deque 队列动态管理候选节点,支持高效头尾操作。

● size 提前记录队列长度,避免循环中动态计算影响效率。

● 回溯时通过 pop_back() 撤销子节点,确保不重复遍历。

五、总结

1. 算法优势:回溯算法天然适合路径搜索问题,通过队列管理候选节点,避免深度递归溢出风险。

2. 优化方向:若题目允许去重或剪枝,可进一步优化时间复杂度,但原解法已满足面试需求。

3. 应用场景:适用于需要生成所有组合、排列的树结构问题,如力扣其他序列化/构造类题目。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

题目解读给定一个不含重复元素的整数数组,我们需要构建一棵最大二叉树。构建规则是:数组中的最大值作为根节点,其左侧子数组构建左子树,右侧子数组构建右子树,然后递归地应用这个规则。这种构建方式体现了分治思...

力扣94:递归之美 轻松掌握二叉树中序遍历

力扣94:递归之美 轻松掌握二叉树中序遍历

题目解读二叉树的中序遍历是一种基础且重要的树遍历方式,其遍历顺序为:先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。对于二叉搜索树,中序遍历的结果恰好是节点值的升序排列。给定一个二叉...

CSP-J 2019公交换乘题解析:基于队列优化的动态规划代码详解

CSP-J 2019公交换乘题解析:基于队列优化的动态规划代码详解

一、题目解读CSP-J 2019年的“公交换乘”题目(洛谷P5661)要求模拟地铁与公交交替出行的费用计算。题目核心在于地铁消费会产生优惠券,而公交可在45分钟内使用优惠券抵扣车费。需要处理n条出行记...

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

一、题目解读力扣2846题要求解决一个基于图连通性的操作优化问题。给定一个无向图,包含边权重,以及一系列查询,每个查询询问两点间路径的最小操作次数。题目关键在于高效计算路径上权重分布的统计信息,并转化...

力扣面试题02.05链表相加:虚拟头节点+迭代解法的详细解析

力扣面试题02.05链表相加:虚拟头节点+迭代解法的详细解析

一、题目解读力扣面试题02.05要求将两个链表表示的整数相加,每个节点存储一位数字(逆序),结果同样以链表形式返回。例如,链表1为7→2→4,链表2为5→6→3,相加结果应为2→9→8→7。题目难点在...

洛谷P3694题解:动态规划与状态压缩优化解题全解析

洛谷P3694题解:动态规划与状态压缩优化解题全解析

一、题目解读洛谷P3694题要求解决一个多团队人数分配问题,给定n个元素和m个团队,每个元素属于一个团队,需将元素重新排列,使相邻元素属于不同团队,并最小化调整次数。题目难点在于如何高效处理团队间的空...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。