199. 二叉树的右视图
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
if (!root)
return {};
vector<int> V;
queue<TreeNode *> Q;
Q.push(root);
while (!Q.empty()) {
TreeNode *Right = Q.back();
V.push_back(Right->val);
int Size = Q.size();
for (int i = 0; i < Size; ++i) {
TreeNode *TN = Q.front();
Q.pop();
if (TN->left)
Q.push(TN->left);
if (TN->right)
Q.push(TN->right);
}
}
return V;
}
};
层序遍历模板题。二刷的时候用深搜写一下。
二刷
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
std::queue<TreeNode *> Q;
std::vector<int> Result;
if (!root)
return {};
Q.push(root);
while (!Q.empty()) {
int LayerSize = Q.size();
for (int i = 0; i < LayerSize; ++i) {
TreeNode *This = Q.front();
Q.pop();
if (This->left)
Q.push(This->left);
if (This->right)
Q.push(This->right);
if (i == LayerSize - 1)
Result.push_back(This->val);
}
}
return Result;
}
};
没什么好说的,层序遍历而已。但是你仔细看的话会发现我一刷的时候那个解法是更好的,避免了这个蹩脚的 i == LayerSize - 1 的判定。
至于递归深搜,也很好写,先访问右子树即可。
class Solution {
vector<int> Result;
void Traverse(TreeNode *TN, int Depth) {
if (!TN)
return;
if (Depth == Result.size())
Result.push_back(TN->val);
Traverse(TN->right, Depth + 1);
Traverse(TN->left, Depth + 1);
}
public:
vector<int> rightSideView(TreeNode* root) {
Traverse(root, 0);
return Result;
}
};
迭代深搜注意栈是后进先出的,所以 emplace() 的顺序确实是先 left 再 right。
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> Result;
// type Pair = (TN, Depth);
stack<pair<TreeNode *, int>> S;
S.emplace(root, 0);
while (!S.empty()) {
auto [TN, Depth] = S.top();
S.pop();
if (!TN)
continue;
if (Depth == Result.size())
Result.push_back(TN->val);
// Stack is FILO, so [left, right] -> [right, left]. This is correct. If
// we want a normal traversal, that's the time we push right first.
S.emplace(TN->left, Depth + 1);
S.emplace(TN->right, Depth + 1);
}
return Result;
}
};
先右后左的前序遍历,外加对 Result.size() 的判断,保证了当且仅当我们访问到每一层的最右节点,Result 得以更新。
三刷
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
if (!root)
return {};
vector<int> Result;
queue<TreeNode *> Q;
Q.push(root);
while (!Q.empty()) {
int Size = Q.size();
for (int i = 0; i < Size; ++i) {
TreeNode *TN = Q.front();
Q.pop();
if (i == Size - 1)
Result.emplace_back(TN->val);
if (TN->left)
Q.push(TN->left);
if (TN->right)
Q.push(TN->right);
}
}
return Result;
}
};
还是采用了二刷而非一刷的写法。不过一刷那个Q.back()确实聪明啊。