Leetcode 971:反转二叉树以匹配先序遍历

题目描述

给定一个有N个结点的二叉树,每个结点都有一个不同于其他结点且处于{1,....,N}中的值。通过交换节点的左子节点和右子节点,可以反转该二叉树中的节点。考虑从根节点开始的先序遍历报告的N值序列。将这一N值序列称为树的行程。(回想一下,节点的先序遍历意味着我们报告当前节点的值,然后先序遍历左子节点,再先序遍历右子节点。)我们的目标是反转最少的树中节点,以便树的行程与给定的行程voyage相匹配。如果可以,则返回反转的所有节点的值的列表。你可以按任何顺序返回答案。如果不能,则返回列表[-1]。

示例1

输入:root = [1,2],voyage = [2,1]

输出:-1

示例2

输入:root = [1,2,3],voyage = [1,3,2]

输出:[1]

示例3

输入:root = [1,2,3],voyage = [1,2,3]

输出:[]

解题思路

由于本人水平太差,在本题上花费了比较长的时间。在这里也分享一下刷题体会,由于本题一定是在树的先序遍历基础上进行算法扩充,同时有树的反转操作。于是本人第一次尝试是编写一个反转树的函数,然后编写树的先序遍历非递归形式,一开始根节点入栈,voyage行程索引0入栈;然后占不空时出栈并判断当前节点的右子树值是否等于2*topi+2,等于入栈,否则反转,反转之后再进行判断;左子树节点也进行相同的操作。导致算法写起来臃肿并且bug不断。后来参考评论区大佬的思想(与大佬的差距还是太大,刷题不能停啊):其实树的反转操作并不一定要真实的改变树的结构,而是只需要将原本的dfs(root->left)写在dfs(root->right)后边即可(看完大佬的解答拍案叫绝啊!而且这种改变递归顺序等价转换成改变树结构的思想仿佛之前刷题遇到过,但是没能反应过来。。。水平还是很菜,仍需不断努力)。

vector<int> vect;
    int idx = 0;
    void dfs(TreeNode* root,vector<int>& voyage){
        if(vect.size()>0 && vect[0] == -1) return;
        if(root != NULL){
            if(root->val != voyage[idx]){
                vect.clear();
                vect.push_back(-1);
                return;
            }
            idx++;
            if(idx < voyage.size() && root->left!=NULL && root->left->val != voyage[idx]){
                vect.push_back(root->val);
                dfs(root->right,voyage);
                dfs(root->left,voyage);
            }else{
                dfs(root->left,voyage);
                dfs(root->right,voyage);
            }
        }
    }
    vector<int> flipMatchVoyage(TreeNode* root, vector<int>& voyage) {
        dfs(root,voyage);
        if(idx < voyage.size()){
            vect.clear();
            vect.push_back(-1);
        }
        return vect;
    }

猜你喜欢

转载自blog.csdn.net/weixin_35338624/article/details/87953647
今日推荐