971. Flip Binary Tree To Match Preorder Traversal

971. Flip Binary Tree To Match Preorder Traversal

Given a binary tree with N nodes, each node has a different value from 1, …, N. A node in this binary tree can be flipped by swapping the left child and the right child of that node. Our goal is to flip the least number of nodes in the tree so that the voyage of the tree matches the voyage we are given. If we can do so, then return a list of the values of all nodes flipped.  You may return the answer in any order. If we cannot do so, then return the list -1

思路

树的深度优先遍历DFS,根节点的值首先要匹配数组里下标i对应的值,遍历的返回值是布尔类型,表示是否反转成功,每次 DFS 递归执行一次,i 就会自增,不用翻转,则继续遍历,如果需要翻转,需要事先判断是否能够翻转** (左右子树都必须存在) **,第一次实现的时候漏掉了这个 corner case

最优解

class Solution {
public:
    vector<int> flipMatchVoyage(TreeNode* root, vector<int>& voyage) {
        if (flip(root, voyage)) return res;
        // If failed to flip, clear exist element in res
        res.clear();
        res.push_back(-1);
        return res;
    }
    
    bool flip(TreeNode* root, vector<int>& v) {
        if (root == NULL) return true;
        if (root->val != v[i]) return false;
        
        ++i;
        if (root->left && root->left->val == v[i]) {
            return flip(root->left, v) && flip(root->right, v);
        } else if (root->right && root->right->val == v[i]) {
            // Flip needs two children not null ?? 题目划线部分重点!!
            if (root->left)
                res.push_back(root->val);
            return flip(root->right, v) && flip(root->left, v);
        }
        // It may no children
        return !root->left && !root->right;
    }
    
    vector<int> res;
    int i=0;
};

收获

前序遍历的数组的生成本身就与先访问左子树还是先访问右子树有关,因此翻转类型的题目也无非就是递归的时候换一下顺序,然后在这中间做一些满足题目的操作

#tree