【两棵树 对比】100. Same Tree; 101. Symmetric Tree; 951. Flip Equivalent Binary Trees; 116. Populating Next Right Pointers in Each Node;
二叉树 Binary Tree
-【两棵树 对比】
问题:
给定 层序遍历的数组 表示二叉树。
- 100. 判断两棵二叉树是否相同。
-
Example 1: Input: 1 1 / \ / \ 2 3 2 3 [1,2,3], [1,2,3] Output: true Example 2: Input: 1 1 / \ 2 2 [1,2], [1,null,2] Output: false Example 3: Input: 1 1 / \ / \ 2 1 1 2 [1,2,1], [1,1,2] Output: false
- 101. 判断一颗二叉树是否 关于中心轴 对称。
-
For example, this binary tree [1,2,2,3,4,4,3] is symmetric: 1 / \ 2 2 / \ / \ 3 4 4 3 But the following [1,2,2,null,3,null,3] is not: 1 / \ 2 2 \ \ 3 3 Follow up: Solve it both recursively and iteratively.
- 951. 判断两棵树,是否互为 翻转对称。
- (只是对调自己的左右子节点,但是不会递归翻转所有子节点。如下面的节点2作为1的子孩子被翻转,但是2的左右子节点4和5的左右关系不变)
-
-
Example 1: Flipped Trees Diagram 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: The number of nodes in each tree is in the range [0, 100]. Each tree will have unique node values in the range [0, 99].
-
116. 给完美二叉树的各个节点的next赋值,指向其正右边节点。(若没有,赋值null)
-
-
Example 1: Input: root = [1,2,3,4,5,6,7] Output: [1,#,2,3,#,4,5,6,7,#] Explanation: Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level. Constraints: The number of nodes in the given tree is less than 4096. -1000 <= node.val <= 1000
解法:Binary Tree (二叉树)
模版:两棵树问题:
1 def solve(p,q) 2 // 无效节点处理 3 if not p and not q: return... 4 // 递归终点,base 5 if f(p, q): return... 6 // 对两棵树的子节点,分类递归,讨论 7 c1 = solve(p->child, q->child) 8 c2 = solve(p->child, q->child) 9 ... 10 // 总结分类讨论 11 return g(c1, c2, ..., p, q) 12 end
100. 判断两棵二叉树是否相同。
代码参考:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 * }; 11 */ 12 class Solution { 13 public: 14 bool isSameTree(TreeNode* p, TreeNode* q) { 15 if(!p && !q) return true; 16 else if(!p || !q) return false; 17 bool c1 = isSameTree(p->left, q->left); 18 bool c2 = isSameTree(p->right, q->right); 19 return c1 && c2 && p->val==q->val; 20 } 21 };
101. 判断一颗二叉树是否 关于中心轴 对称。
1. 递归 recursively(本模版做法)
代码参考:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 * }; 11 */ 12 class Solution { 13 public: 14 bool isSym(TreeNode* p, TreeNode* q) { 15 if(!p && !q) return true; 16 else if(!p || !q) return false; 17 bool c1 = isSym(p->left, q->right); 18 bool c2 = isSym(p->right, q->left); 19 return c1 && c2 && p->val==q->val; 20 } 21 bool isSymmetric(TreeNode* root) { 22 if(!root) return true; 23 return isSym(root->left, root->right); 24 } 25 };
2. 迭代 iteratively(while循环做法:引入队列queue->保存递归中的每层函数调用)
代码参考:
1 class Solution { 2 public: 3 bool isSymmetric(TreeNode* root) { 4 TreeNode *l, *r; 5 if(!root) return true; 6 l = root->left; 7 r = root->right; 8 queue<TreeNode*> p, q; 9 p.push(l); 10 q.push(r); 11 while(!p.empty() || !q.empty()) { 12 l = p.front(); 13 r = q.front(); 14 p.pop(); 15 q.pop(); 16 if(!l && !r) { 17 continue; 18 } else if(!l || !r || l->val != r->val) { 19 return false; 20 } 21 p.push(l->left); 22 p.push(l->right); 23 q.push(r->right); 24 q.push(r->left); 25 } 26 return true; 27 } 28 };
⚠️ 注意:
仍然是划分为两棵树 p,q 做对比。
最后压栈时,将要进行对比的两颗子树,分别放入p和q中。
例如,我们下一次要对比 l->left VS r->right
那么将l->left 压入p,同时,将r->right 压入q。
这样,将来同时弹栈时,会正好弹出这两个对象,进行对比。
951. 判断两棵树,是否互为 翻转对称。
代码参考:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 * }; 11 */ 12 class Solution { 13 public: 14 bool flipEquiv(TreeNode* root1, TreeNode* root2) { 15 if(!root1 && !root2) return true; 16 if(!root1 || !root2) return false; 17 bool c1 = flipEquiv(root1->left, root2->left); 18 bool c2 = flipEquiv(root1->right, root2->right); 19 bool c3 = flipEquiv(root1->left, root2->right); 20 bool c4 = flipEquiv(root1->right, root2->left); 21 return ( c1&&c2 || c3&&c4 ) && root1->val==root2->val; 22 } 23 };
⚠️ 注意:
c1和c2: 未翻转,相同。
c3和c4:翻转后,相同
116. 给完美二叉树的各个节点的next赋值,指向其正右边节点。
代码参考:
1 /* 2 // Definition for a Node. 3 class Node { 4 public: 5 int val; 6 Node* left; 7 Node* right; 8 Node* next; 9 10 Node() : val(0), left(NULL), right(NULL), next(NULL) {} 11 12 Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {} 13 14 Node(int _val, Node* _left, Node* _right, Node* _next) 15 : val(_val), left(_left), right(_right), next(_next) {} 16 }; 17 */ 18 19 class Solution { 20 public: 21 void connectTwoNode(Node* node1, Node* node2) { 22 if(!node1 || !node2) return; 23 node1->next = node2; 24 25 connectTwoNode(node1->left, node1->right);//node1: left->right 26 connectTwoNode(node2->left, node2->right);//node2: left->right 27 connectTwoNode(node1->right, node2->left);//## node1.right->node2.left 28 } 29 Node* connect(Node* root) { 30 if(!root) return root; 31 connectTwoNode(root->left, root->right); 32 return root; 33 } 34 };
⚠️ 注意:
按照题意,本题涉及连接两个节点,node1和node2。
因此追加函数connectTwoNode,完成递归。
- 递归base结束条件:node1==null || node2==null
- 针对每一次node1和node2的连接,有以下操作:
- 自身操作:连接node1和node2: node1->next=node2
- 递归:连接子节点们:
- node1.left->node1.right
- node2.left->node2.right
- node1.right->node2.left