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 <= N <= 100
這道題給了一棵二叉樹,說是我們可以調換任意結點的左右子結點,又給了一個數組,說是按照先序遍歷二叉樹得到的結點值組成的。現在問能否通過最少的調換操作,使得給定的二叉樹經過先序遍歷得到的結點值數組和給定的數組相同,可以的話返回需要調換操作的結點值,否則返回 -1。遇到二叉樹的問題,十有八九都是遞歸來做的,這道題也不例外,而且又是先序遍歷,妥妥的遞歸啊。難點在於如何在遞歸的過程中把問題解決了,由於我們需要在遞歸的過程中就和給定數組進行比較,所以 voyage 數組是要在遞歸數組中的,這樣就需要一個子函數進行遞歸調用,而且還要知道當前對比到哪個位置了,需要一個坐標變量傳入,同時當然還要傳入結果數組 res。同時這個遞歸函數需要返回一個布爾值,因為有可能是無法生成跟給定數組一樣的順序的。在遞歸函數中,若當前結點不存在,直接返回 true。若當前結點值不等於數組中的對應位置的值,直接返回 false,因為此時只能調換子結點的位置,當前結點的位置不會改變。否則此時看若左子結點存在,且左子結點值不等於數組中對應位置的值,此時應該嘗試進行翻轉,先將當前結點值存入結果 res 中,然后先對右子結點調用遞歸函數,之后再對左子結點調用遞歸函數,這樣就相當於完成了調換左右子結點的操作。否則就按原順序分別對左右子結點調用遞歸函數即可,最終在主函數中對於遞歸函數的返回值需要做個判斷,若為 true,則返回 res,否則返回一個只有 -1 的數組,參見代碼如下:
class Solution {
public:
vector<int> flipMatchVoyage(TreeNode* root, vector<int>& voyage) {
vector<int> res;
int i = 0;
return helper(root, voyage, i, res) ? res : vector<int>{-1};
}
bool helper(TreeNode* node, vector<int>& voyage, int& i, vector<int>& res) {
if (!node) return true;
if (node->val != voyage[i++]) return false;
if (node->left && node->left->val != voyage[i]) {
res.push_back(node->val);
return helper(node->right, voyage, i, res) && helper(node->left, voyage, i, res);
}
return helper(node->left, voyage, i, res) && helper(node->right, voyage, i, res);
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/971
參考資料:
https://leetcode.com/problems/flip-binary-tree-to-match-preorder-traversal/