https://leetcode.com/problems/flip-equivalent-binary-trees/
For a binary tree T, we can define a flip operation as follows: choose any node, and swap the left and right child subtrees.
A binary tree X is flip equivalent to a binary tree Y if and only if we can make X equal to Y after some number of flip operations.
Given the roots of two binary trees root1
and root2
, return true
if the two trees are flip equivelent or false
otherwise.
Example 1:
Input: root1 = [1,2,3,4,5,6,null,null,null,7,8], root2 = [1,3,2,null,6,4,5,null,null,null,null,8,7] Output: true Explanation: We flipped at nodes with values 1, 3, and 5.
Example 2:
Input: root1 = [], root2 = [] Output: true
Example 3:
Input: root1 = [], root2 = [1] Output: false
Example 4:
Input: root1 = [0,null,1], root2 = [] Output: false
Example 5:
Input: root1 = [0,null,1], root2 = [0,1] Output: true
Constraints:
[0, 100]
.[0, 99]
./**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
简单的递归,重点理解思路
class Solution {
public:
bool flipEquiv(TreeNode* root1, TreeNode* root2) {
if (root1 == nullptr && root2 == nullptr) return true;
if (root1 == nullptr || root2 == nullptr) return false;
if (root1->val != root2->val) return false;
bool nonFlip = flipEquiv(root1->left, root2->left)
&& flipEquiv(root1->right, root2->right);
bool flip = flipEquiv(root1->left, root2->right)
&& flipEquiv(root1->right, root2->left);
return nonFlip || flip;
}
};
Approach 2: Canonical Traversal
Intuition
Flip each node so that the left child is smaller than the right, and call this the canonical representation. All equivalent trees have exactly one canonical representation.
Algorithm
We can use a depth-first search to compare the canonical representation of each tree. If the traversals are the same, the representations are equal.
When traversing, we should be careful to encode both when we enter or leave a node.
class Solution {
public boolean flipEquiv(TreeNode root1, TreeNode root2) {
List vals1 = new ArrayList();
List vals2 = new ArrayList();
dfs(root1, vals1);
dfs(root2, vals2);
return vals1.equals(vals2);
}
public void dfs(TreeNode node, List vals) {
if (node != null) {
vals.add(node.val);
// unique node values in the range [0, 99]
int L = node.left != null ? node.left.val : -1;
int R = node.right != null ? node.right.val : -1;
if (L < R) {
dfs(node.left, vals);
dfs(node.right, vals);
} else {
dfs(node.right, vals);
dfs(node.left, vals);
}
vals.add(null);
}
}
}