题目地址:
https://leetcode.com/problems/invert-binary-tree/
翻转二叉树。首先要明确翻转的定义是什么,这里定义是递归的:
1、如果树为空或者只有一个节点,就不翻转
2、否则对调树的左右子树,并翻转左右子树。
翻转也有一个非递归定义,即:将树的每一层的数的顺序反转。
根据第一种定义,可以用分治法:
/**
* 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:
TreeNode* invertTree(TreeNode* root) {
if (!root) return root;
invertTree(root->right);
invertTree(root->left);
swap(root->left, root->right);
return root;
}
};
时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( h ) O(h) O(h)。
上述思路也可以用BFS来实现。根据第二种定义,代码不太好写。不过不妨证明一下这两个定义是等价的。定义的等价性,等价于证明,对于 2 k 2^k 2k个数的逆序列 ( n , n − 1 , . . . , 1 ) (n,n-1,...,1) (n,n−1,...,1), n = 2 k n=2^k n=2k,依次进行 2 i , i = 1 , 2 , . . . , k − 1 2^i,i=1,2,...,k-1 2i,i=1,2,...,k−1个翻转后(这里的意思是,先进行两个两个地每组一个swap,再进行四个四个地每组两个swap,这样一直下去。举例: ( 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ) → ( ( 7 , 8 ) , ( 5 , 6 ) , ( 3 , 4 ) , ( 1 , 2 ) ) → ( ( 5 , 6 , 7 , 8 ) , ( 1 , 2 , 3 , 4 ) ) → ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ) (8,7,6,5,4,3,2,1)\rightarrow((7,8),(5,6),(3,4),(1,2))\rightarrow((5,6,7,8),(1,2,3,4))\rightarrow (1,2,3,4,5,6,7,8) (8,7,6,5,4,3,2,1)→((7,8),(5,6),(3,4),(1,2))→((5,6,7,8),(1,2,3,4))→(1,2,3,4,5,6,7,8)),成为 ( 1 , 2 , . . . , n ) (1,2,...,n) (1,2,...,n)。由数学归纳法,显然。