casyup.me@outlook.com

0%

leetcode/116PopulatingNextRightPointersInEachNode

Populating Next Right Pointers in Each Node

给了一个完美的二叉树, 填充其next节点

my solution (60ms, 90.37%)

这道题我给出了两种方案, 递归和迭代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
static const int _ = [] () {
ios::sync_with_stdio(false);
cin.tie(nullptr);

return 0;
} ();

class Solution {
public:
// Node* connect(Node* root) {
// if (!root)
// return root;
//
// vector<Node*> lev;
// lev.push_back(root);
//
// while ( !lev.empty() ) {
// vector<Node*> nlev;
// int size = lev.size();
//
// int i = 0, i2 = 1;
// for (; i2 < size; ++i, ++i2) {
// lev[i]->next = lev[i2];
// if ( lev[i]->left ) {
// nlev.push_back( lev[i]->left );
// nlev.push_back( lev[i]->right );
// }
// }
// lev[i]->next = nullptr;
// if ( lev[i]->left ) {
// nlev.push_back( lev[i]->left );
// nlev.push_back( lev[i]->right );
// }
//
// swap(lev, nlev);
// }
//
// return root;
// }

Node* connect(Node* root) {
if (!root) return root;

connect_two(root->left, root->right);

return root;
}

void connect_two(Node* left, Node* right) {
if (!left) return;

left->next = right;
if (left->left)
connect_two(left->left, left->right);
connect_two(left->right, right->left);
connect_two(right->left, right->right);
}
};

对于迭代, 我将每一级的元素都保留, 然后用作下一次迭代

递归的话, 因为如果只是单节点传参, 始终会面临有缝隙的情况, 所以用双节点传参

递归的代码更加简洁, 我推荐使用递归

emmmm… 速度上还好, 但是内存上就很不能接受了

(我很好奇, 代码量已经很少了, 而且递归中也不会产生多余的操作)

(难道是在 perfect binary tree 上能有什么绚丽的操作么?)

best solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void connect(TreeLinkNode *root) {
queue<TreeLinkNode*> q;
if (!root){
return;
}

q.push(root);

while (!q.empty()){
int size = q.size();
while (size--){
TreeLinkNode* c = q.front();
q.pop();

if (size == 0){
c->next = NULL;
}
else{
c->next = q.front();
}

if (c->left){
q.push(c->left);
}
if (c->right){
q.push(c->right);
}
}
}
return;
}

哦哦哦, 用的是迭代的方式, 只不过他用了队列

而且用了size, 这样也就不需要一个新的容器了, 很不错 -v-

不过既然题说了是 perfect binary tree, 而且next默认为空, 那么可以稍微改良一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Node* connect(Node* root) {
if (!root) return root;

queue<Node*> q;
q.push(root);
while( !q.empty() ) {
int size = q.size();
while (size--) {
Node* cur = q.front();
q.pop();

if (size)
cur->next = q.front();

if (cur->left) {
q.push(cur->left);
q.push(cur->right);
}
}
}

return root;
}

细节在于:

  1. 如果是空节点, 少了一个空 queue 的分配时间
  2. 不用再去赋值 nullptr 了
  3. 少了一个 cur->right 的判断, 因为题目说了是 perfect binary tree

PS: 我最后用这个答案再试了一次, 发现结果和我用递归的结果相差无几…

可能这是增加了测试用例或者改了题的结果? 毕竟 TreeLinkNode 变为了 Node