971. 翻转二叉树以匹配先序遍历
Posted Debroon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了971. 翻转二叉树以匹配先序遍历相关的知识,希望对你有一定的参考价值。
971. 翻转二叉树以匹配先序遍历
题目
传送门:https://leetcode.cn/problems/flip-binary-tree-to-match-preorder-traversal/
算法设计:深度优先搜索
解题思路,对于一个结点:
- 它翻转前可以匹配
voyage
序列,不用翻转 - 若不匹配,就需要翻转左右子树,即遍历顺序从
[根、左、右]
变成[根、右、左]
,若这样匹配voyage
序列,则记录该结点的值。 - 否则,代表这棵树无法匹配
voyage
序列,返回[-1]
。 - 题目要求最少翻转次数,因此不翻转的情况优先级更高,若不匹配再进行翻转。
匹不匹配需要用一个状态值来表示,DFS 方法的返回值可设置为 bool
,表示当前结点及翻转子树前后能否匹配 voyage
序列。
用拆解子问题公式分析:
-
二叉树原问题 = 根节点 + 左右子树问题
-
翻转二叉树是否匹配先序遍历 = 根节点匹配 && (根节点的左右子树匹配 || 翻转后,根节点的左右子树匹配)
class Solution
vector<int> res; // 全局变量存结果
int i = 0; // 匹配voyage第 i 个元素
public:
vector<int> flipMatchVoyage(TreeNode* root, vector<int>& v)
return dfs(root, v) ? res : vector<int>-1; // 匹配voyage,返回翻转结点值,否则无解
bool dfs(TreeNode* node, vector<int>& v)
if (!node) return true; // 空树 或 当前节点及左右子树匹配,不用翻转
if (node->val != v[i]) return false; // 当前结点不匹配voyage
++ i; // 当前节点匹配,再判断左右子树是否匹配
if (node->left && node->left->val != v[i]) // 左叶子存在 且 左叶子值与voyage不匹配,就翻转
res.push_back(node->val); // 记录这次翻转的值
return dfs(node->right, v) && dfs(node->left, v); // 翻转遍历(先右后左)
else // 左叶子不存在 或 左叶子值匹配,就不用翻转
return dfs(node->left, v) && dfs(node->right, v); // 遍历左右子树
;
以上是关于971. 翻转二叉树以匹配先序遍历的主要内容,如果未能解决你的问题,请参考以下文章