二叉树的前序遍历串是否合法
bool isValidSerialization(string preorder) {
// 想象扫描串并构建树,在扫描串的过程中要确保"叶节点数<内节点数+1",
// 一旦"叶节点数=内节点数+1"则树已构建好不能再扩展,要确保扫描完。
// 设diff=叶节点数-内节点数,扫描过程中确保diff<1,一旦diff==1确保扫描完。
const int N = preorder.size();
int diff = 0, i = 0;
while (i < N) {
if (preorder[i++] == '#') diff++;
else diff--;
if (diff == 1) break;
// 向前直到','
while (i < N && preorder[i] != ',') i++;
if (i < N) i++;
}
return i == N && diff == 1;
}
可交换节点的左右子树,为使前序遍历结果符合给定顺序,要在哪些节点做交换
vector<int> flipMatchVoyage(TreeNode* root, vector<int>& voyage) {
vector<int> ans;
int idx = 0; // 类似表达式解析问题,有个idx记录解析位置
if (match(root, voyage, idx, ans)) return ans;
return {-1};
}
bool match(TreeNode* root, vector<int>& voyage, int &idx, vector<int> &ans) {
if (!root) return true;
if (root->val != voyage[idx++]) return false;
if (root->left && root->left->val != voyage[idx]) {
ans.push_back(root->val); // flip
return match(root->right, voyage, idx, ans)
&& match(root->left, voyage, idx, ans);
}
return match(root->left, voyage, idx, ans)
&& match(root->right, voyage, idx, ans);
}
扩展:从前序遍历数组构造bst