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

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

2个月前 (08-05)

力扣面试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题:最大二叉树解题教程 用数组构造最大二叉树

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

力扣933题:队列的妙用:如何高效统计最近请求

力扣933题:队列的妙用:如何高效统计最近请求

题目重解:我们需要设计一个能统计最近3000毫秒内请求次数的系统。每当新的请求到来时,它会带有时间戳t,我们需要返回过去3000毫秒内(包括当前)发生的请求总数。这就像是在时间轴上维护一个滑动窗口,只...

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

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

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

力扣面试16.18题解析:模式匹配问题的算法优化与实现(动态规划+字符串匹配)

力扣面试16.18题解析:模式匹配问题的算法优化与实现(动态规划+字符串匹配)

一、题目解读力扣面试16.18题要求判断字符串value是否可通过替换模式串pattern中的字符"a"和"b"(任意非空子串)进行匹配。例如,模式"...

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

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

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

洛谷P1141题解:迷宫连通块问题的深度优先搜索算法与代码解析

洛谷P1141题解:迷宫连通块问题的深度优先搜索算法与代码解析

一、题目解读洛谷P1141题目要求处理一个由字符构成的迷宫,其中相同字符形成连通块,不同字符构成分隔。题目需统计连通块数量及大小,并支持查询两点是否属于同一连通块。核心在于高效识别并标记迷宫中的连通区...

发表评论

访客

看不清,换一张

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