LeetCode 114. 二叉树展开为链表 题解
题目描述
![1b46ca188b75882f85a4808bdf82fa55.png](https://i-blog.csdnimg.cn/blog_migrate/3163cc488102a1d66de0c0ee6635c533.png)
思路1:前序遍历
根据题意,我们要把所有的点按前序遍历的顺序将他们连成一条链,所以在这里最基础的做法就是对树进行前序遍历,并将这些节点记录起来。遍历结束后,我们将这些点按顺序链好即可。
实现细节
使用队列记录前序遍历的节点顺序。依次出队重新链到树上。切勿忘记将每个节点的左儿子设为空。
代码
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */class Solution {public: queue q; void dfs(TreeNode* now){ q.push(now); if(now->left) dfs(now->left); if(now->right) dfs(now->right); } void flatten(TreeNode* root) { if(root==NULL) return; dfs(root); TreeNode* now = q.front(); q.pop(); while(!q.empty()){ TreeNode* tmp = q.front(); q.pop(); now->right = tmp; now->left = NULL; now = now->right; } }};
复杂度
时间复杂度:深搜时间复杂度。
空间复杂度:队列存节点空间复杂度。
思路2:记录前驱节点
首先,我们可以用前序遍历的思维理解一下这道题。在进行前序遍历时,对于一个节点,在访问完它左子树中的所有节点后,再去访问它右子树的第一个节点,也就是该点的右儿子。在本题中,该点的右儿子就应该和该点左子树的最后一个节点链接,而左子树最后一个节点就是子树中最右的节点,所以这个点就是前驱点,我们只需要找到这个点就可以了。
代码
class Solution {public: void flatten(TreeNode* root) { TreeNode *now = root; while (now) { if (now->left) { TreeNode* next = now->left; TreeNode* pre = next; while (pre->right) pre = pre->right; pre->right = now->right; now->left = NULL; now->right = next; } now = now->right; } }};
复杂度
时间复杂度:遍历时间复杂度。
空间复杂度:仅记录前驱点、根节点等关键节点空间复杂度。