623. 在二叉树中增加一行
题目描述:
给定一个二叉树,根节点为第1层,深度为 1。在其第 d
层追加一行值为 v
的节点。
添加规则:
给定一个深度值 d
(正整数),针对深度为 d-1
层的每一非空节点 N
,为 N
创建两个值为 v
的左子树和右子树。
将 N
原先的左子树,连接为新节点 v
的左子树;将 N
原先的右子树,连接为新节点 v
的右子树。
如果 d
的值为 1,深度 d - 1 不存在,则创建一个新的根节点 v
,原先的整棵树将作为 v
的左子树。
示例 1:
示例 2:
注意:
- 输入的深度值 d 的范围是:[1,二叉树最大深度 + 1]。
- 输入的二叉树至少有一个节点。
题意:
题目描述还算是蛮清晰的,给定一棵树,再给要插入的节点值v和插入的层数d,默认根节点所在为第1层。插入规则上面也说得比较清楚了。
算法:
对树进行层次遍历,要在每一层的遍历中记录当前的层数depth,下面看伪代码
if 要插入的层数 = 第一层:
插入,
返回;
else
LOOP:
if 当前层数 = 要插入的层数 - 1:
插入;
返回;
遍历;
获取当前层数;
大致的代码框架如上了,就是要考虑如何获取是第几层,以及符合规则的插入操作,下面给c++代码。
1 #include <queue> 2 using namespace std; 3 4 class Solution { 5 public: 6 TreeNode* addOneRow(TreeNode* root, int v, int d) { 7 //d是层数,root是第1层,记得在depth=d-1时插入v 8 if(d == 1) 9 { 10 TreeNode *newNode = new TreeNode(v); 11 newNode->left = root; 12 root = newNode; 13 return root; 14 } 15 queue<TreeNode*> Q; 16 int depth = 1; 17 Q.push(root); 18 19 //parameters 20 int nodesOfCurrentFloor = 1; //记录当前层的总节点个数,第一层显然为1 21 22 //记录下一层总节点的个数,初始为0,要在队列操作时才能知晓下一层共有多少个节点 23 int nodesOfNextFloor = 0; 24 25 int nowNodes = 0; //在当前层已经访问到的(出队)的结点个数 26 27 while( !Q.empty() ) { 28 //插入 29 if(depth == d - 1) 30 { 31 while(!Q.empty() ) //当前队列中都是d-1层的结点,依次弹出,改变它们的子节点 32 { 33 TreeNode *q = Q.front(), *tmpLeft, *tmpRight; 34 Q.pop(); 35 tmpLeft = tmpRight = nullptr; 36 if(q->left) 37 tmpLeft = q->left; 38 if(q->right) 39 tmpRight = q->right; 40 TreeNode *appendNode1 = new TreeNode(v); 41 TreeNode *appendNode2 = new TreeNode(v); 42 q->left = appendNode1; 43 q->right = appendNode2; 44 appendNode1->left = tmpLeft; 45 appendNode2->right = tmpRight; 46 } 47 break; 48 } 49 50 TreeNode *p = Q.front(); 51 Q.pop(); 52 nowNodes++; 53 if(p->left) 54 { 55 Q.push(p->left); 56 nodesOfNextFloor++; 57 } 58 59 if(p->right) 60 { 61 Q.push(p->right); 62 nodesOfNextFloor++; 63 } 64 65 if(nowNodes == nodesOfCurrentFloor) 66 { 67 //判别是否已经当这一层的最后一个节点,如果是,层数+1,并且重设上面3个参数的值 68 depth++; 69 nodesOfCurrentFloor = nodesOfNextFloor; 70 nodesOfNextFloor = nowNodes = 0; 71 } 72 } 73 cout << endl; 74 return root; 75 } 76 };