It 's expensive and not necessary to use hash to check whether the node is visited.

Because there are at most three node may visited twice or more, which are root, left most leaf and right most leaf node.

Here is the code for reference,

class Solution {
TreeNode *_root, *_left, *_right;
void travel_left(TreeNode *root, vector<int> &left) {
while (root) {
left.push_back(root->val);
_left = root;
if (root->left) root = root->left;
else root = root->right;
}
}
void travel_leaves(TreeNode *root, vector<int> &leaves) {
if (!root) return;
if (!root->left && !root->right && root != _left && root != _root) {
leaves.push_back(root->val);
_right = root;
return;
}
travel_leaves(root->left, leaves);
travel_leaves(root->right, leaves);
}
void travel_right(TreeNode *root, vector<int> &right) {
while (root) {
if (root != _right)
right.push_back(root->val);
if (root->right) root = root->right;
else root = root->left;
}
}
public:
vector<int> boundaryOfBinaryTree(TreeNode* root) {
_root = root;
_left = _right = nullptr;
vector<int> left, leaves, right, ans;
if (!root) return ans;
left.push_back(root->val);
travel_left(root->left, left);
travel_leaves(root, leaves);
travel_right(root->right, right);
ans.insert(ans.end(), left.begin(), left.end());
ans.insert(ans.end(), leaves.begin(), leaves.end());
ans.insert(ans.end(), right.rbegin(), right.rend());
return ans;
}
};