作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/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.

Consider the sequence of N values reported by a preorder traversal starting from the root. Call such a sequence of N values the voyage of the tree.

(Recall that a preorder traversal of a node means we report the current node’s value, then preorder-traverse the left child, then preorder-traverse the right child.)

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].

Example 1:

Input: root = [1,2], voyage = [2,1]
Output: [-1]

Example 2:

Input: root = [1,2,3], voyage = [1,3,2]
Output: [1]

Example 3:

Input: root = [1,2,3], voyage = [1,2,3]
Output: []

Note:

  1. 1 <= N <= 100

题目大意

最少翻转哪些节点,能使得二叉树的前序遍历变成voyage.

解题方法

前序遍历

其实这个题不难,因为题目就说了是前序遍历,所以做法肯定还是前序遍历。我刚开始一直想不通的地方在于,题目又是返回[-1],又是正常返回,没想好怎么做区分。其实做法就是递归函数不仅要修改res数组,还要返回表示能不能构成题目条件的bool变量。

按照lee215的说法,看到二叉树的题,很大可能就需要递归,所以直接先写出dfs函数,然后再慢慢向里面填东西。

我们定义的dfs函数意义是,我们能不能通过翻转(或者不翻转)该root节点的左右子树,得到对应v。如果能,返回true,否则返回false。

首先在递归函数中,我们对root节点进行判断,如果root不存在,这种情况不应该认为是题目输入错误,而是应该认为已经遍历到最底部了,这个时候相当于root = [], voyage = [],所以返回true;在先序遍历的时候,root节点是第一个要被遍历到的节点,如果不和voyage[0]相等,直接返回false;

这个题目的难点在于是否需要翻转一个节点的左右孩子。判断的方法其实是简单的:如果voyage第二个元素等于root的左孩子,那么说明不用翻转,直接递归调用左右孩子;否则如果voyage的第二个元素等于root的右孩子,那么还要注意一下,在左孩子存在的情况下,我们需要翻转当前的节点左右孩子。

翻转是什么概念呢?这里并没有直接交换,而是把当前遍历到的位置使用遍历i保存起来,这样voyage[i]就表示当前遍历到哪个位置了。所以dfs调用两个孩子的顺序很讲究,它体现了先序遍历先解决哪个树的问题,也就是完成了逻辑上的交换左右孩子。

C++代码如下:

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int i = 0;
vector<int> res;
vector<int> flipMatchVoyage(TreeNode* root, vector<int>& voyage) {
res.clear();
if (dfs(root, voyage)) {
return res;
}
return {-1};
}
// can we get v by flip root?
bool dfs(TreeNode* root, vector<int>& v) {
if (!root) return true;
if (root->val != v[i++]) return false;
if (root->left && root->left->val == v[i]) {
return dfs(root->left, v) && dfs(root->right, v);
} else if (root->right && root->right->val == v[i]) {
if (root->left)
res.push_back(root->val);
return dfs(root->right, v) && dfs(root->left, v);
}
return !root->left && !root->right;
}
};

参考资料:https://leetcode.com/problems/flip-binary-tree-to-match-preorder-traversal/discuss/214216/JavaC%2B%2BPython-DFS-Solution

日期

2019 年 1 月 6 日 —— 打球打的腰酸背痛

【LeetCode】971. Flip Binary Tree To Match Preorder Traversal 解题报告(C++)的更多相关文章

  1. LeetCode 971. Flip Binary Tree To Match Preorder Traversal

    原题链接在这里:https://leetcode.com/problems/flip-binary-tree-to-match-preorder-traversal/ 题目: Given a bina ...

  2. LC 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 b ...

  3. [Swift]LeetCode971.翻转二叉树以匹配先序遍历 | 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 b ...

  4. 【LeetCode】 Binary Tree Zigzag Level Order Traversal 解题报告

    Binary Tree Zigzag Level Order Traversal [LeetCode] https://leetcode.com/problems/binary-tree-zigzag ...

  5. 【LeetCode】144. Binary Tree Preorder Traversal 解题报告(Python&C++&Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 迭代 日期 题目地址:https://leetc ...

  6. LeetCode: Binary Tree Preorder Traversal 解题报告

    Binary Tree Preorder Traversal Given a binary tree, return the preorder traversal of its nodes' valu ...

  7. 【一天一道LeetCode】#103. Binary Tree Zigzag Level Order Traversal

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 来源: htt ...

  8. leetCode :103. Binary Tree Zigzag Level Order Traversal (swift) 二叉树Z字形层次遍历

    // 103. Binary Tree Zigzag Level Order Traversal // https://leetcode.com/problems/binary-tree-zigzag ...

  9. 【LeetCode】589. N-ary Tree Preorder Traversal 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 迭代 日期 题目地址:https://leetc ...

随机推荐

  1. 关于GCC编译

    GCC参数详解 gcc是gnu compiler collection 的简称,他包含了多种语言的编译器,如C, C++, Objective-C, Objective-C++, Java, Fort ...

  2. 用C语言的LED实验,有汇编哦!

    C语言LED实验 1.汇编激活CPU 首先要明白对于没有系统开发板(也就是裸机)来说,是没办法直接对C进行识别.所以需要一段汇编语言,来配置CPU的资源,选择CPU运行模式,初始化指针位置. 代码如下 ...

  3. 零基础学习java------23---------动态代理,ip,url案例

    1. 动态代理 2. ip,url案例 给定的access.log是电信运营商的用户上网数据,第一个字段是时间, 第二个字段是ip地址,第三个字段是访问的网站,其他字段可以忽略不计. 第一个字段是网段 ...

  4. C++最小内积

    Description 向量是几何中的一个重要概念. 考虑两个向量 v1=(x1,x2,...,xn)和v2=(y1,y2,...,yn),向量的内积定义为 x1y1+x2y2+...+xnyn 例如 ...

  5. JDK1.8新特性(一): 接口的默认方法default

    前言 今天在学习mysql分区优化时,发现一个博客专家大神,对其发布的文章简单学习一下: 一:简介 我们通常所说的接口的作用是用于定义一套标准.约束.规范等,接口中的方法只声明方法的签名,不提供相应的 ...

  6. Linux基础命令---httpd守护进程

    httpd httpd是apache超文本传输协议的主程序,它被设计成一个独立运行的守护进程.httpd会建立一个线程池来处理http请求. 此命令的适用范围:RedHat.RHEL.Ubuntu.C ...

  7. 【Service】【MiddleWare】【Message】rabbitMQ

    1. 概念: 1.1. 消息型中间件:遵循AMQP协议(高级消息队列协议)AMQP 0-9-1 AMQP 1.0 1.2. 路由模型: direct topic fan-out headers 1.3 ...

  8. 【Linux】【Commands】systemd

    1. 系统启动流程:POST --> Boot Sequeue(BIOS) --> Bootloader(MBR) --> Kernel(ramdisk) --> rootfs ...

  9. Next_day()函数的用法

    一.定义 NEXT_DAY(date,char)  date参数为日期型,  char:为1~7或Monday/Mon~Sunday/    指定时间的下一个星期几(由char指定)所在的日期,  c ...

  10. matplotlib 画图中图和次坐标轴

    一: fig.add_axes 画图中图 fig = plt.figure() x = np.arange(1, 9, 1) y = np.linspace(1, 10, 8) left, botto ...