给定一个二叉树,根节点为第1层,深度为 1。在其第 d 层追加一行值为 v 的节点。
添加规则:给定一个深度值 d (正整数),针对深度为 d-1 层的每一非空节点 N,为 N 创建两个值为 v 的左子树和右子树。
将 N 原先的左子树,连接为新节点 v 的左子树;将 N 原先的右子树,连接为新节点 v 的右子树。
如果 d 的值为 1,深度 d - 1 不存在,则创建一个新的根节点 v,原先的整棵树将作为 v 的左子树。
示例 1:
输入:
二叉树如下所示:
4
/ \
2 6
/ \ /
3 1 5
v = 1
d = 2
输出:
4
/ \
1 1
/ \
2 6
/ \ /
3 1 5
示例 2:
输入:
二叉树如下所示:
4
/
2
/ \
3 1
v = 1
d = 3
输出:
4
/
2
/ \
1 1
/ \
3 1
注意:
输入的深度值 d 的范围是:[1,二叉树最大深度 + 1]。
输入的二叉树至少有一个节点。
思路分析: 典型的递归题。
如果d == 1,特殊情况,插入的层是顶层
否则
如果root的深度deep + 1 == d,说明当前root的下一层是插入层,将新节点插入到root的左右两端
否则,继续往下搜索,知道deep + 1 == d
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* addOneRow(TreeNode* root, int v, int d) {
if (d == 1){//特殊情况,当插入行的位置在顶行
TreeNode *newRoot = new TreeNode(v);
newRoot->left = root;//直接将root放入到新节点的尾端
return newRoot;
}
myAddRow(root, v, d, 1);//否则递归插入
return root;
}
//nowDeep表示root的深度
void myAddRow(TreeNode* root, int v, int d, int nowDeep){
if (root == NULL){//root为空,无法插入
return;
}
if (nowDeep + 1 == d){//当root的下一层是插入层
TreeNode *newLeft = new TreeNode(v), *newRight = new TreeNode(v);//创建新左子节点、右子节点
newLeft->left = root->left;//root的left放到newLeft的left
newRight->right = root->right;//root的right放到newRight的right
root->left = newLeft;//更新root的左子树、右子树
root->right = newRight;
}
else{
//否则继续往下寻找插入的层
myAddRow(root->left, v, d, nowDeep + 1);
myAddRow(root->right, v, d, nowDeep + 1);
}
}
};
方法二:使用层序遍历,首先找到d-1层,然后进行插入。关于层序遍历,请翻阅 LeetCode 二叉树的层次遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* addOneRow(TreeNode* root, int v, int d) {
if (d == 1){//特殊情况,当插入行的位置在顶行
TreeNode *newRoot = new TreeNode(v);
newRoot->left = root;//直接将root放入到新节点的尾端
return newRoot;
}
TreeNode *tempNodePtr;
queue<TreeNode*> myQueue;//辅助队列,用于层次遍历
//第一步:逐层往下移动,直到队列保存第d - 1层
myQueue.push(root);//放入第一层
//初始化队列放了一层,所以这里只能往下移动d - 2层,就能到达第n - 1层
for (int i = 1; i < d - 1; ++i){
int tempQueueSize = myQueue.size();//此时队列的大小(即将访问的层的节点数目)
for (int i = 0; i < tempQueueSize; ++i) {//将此层的所有节点出队列
tempNodePtr = myQueue.front();//获取队头
myQueue.pop();
if (tempNodePtr->left != NULL) {//放置左子树根节点
myQueue.push(tempNodePtr->left);
}
if (tempNodePtr->right != NULL) {//放置右子树根节点
myQueue.push(tempNodePtr->right);
}
}
}
//第二步:在第n-1层后添加一层
while (!myQueue.empty()){
tempNodePtr = myQueue.front();
myQueue.pop();
TreeNode *newLeft = new TreeNode(v), *newRight = new TreeNode(v);//创建新左子节点、右子节点
newLeft->left = tempNodePtr->left;//tempNodePtr的left放到newLeft的left
newRight->right = tempNodePtr->right;//tempNodePtr的right放到newRight的right
tempNodePtr->left = newLeft;//更新tempNodePtr的左子树、右子树
tempNodePtr->right = newRight;
}
return root;
}
};