LeetCode部分习题解答记录-二叉树与递归
111.二叉树的最小深度
方法1:递归
- 代码1:
class Solution {
public int minDepth(TreeNode root) {
if(root == null){
return 0;
}
int left = minDepth(root.left) ;
int right = minDepth(root.right);
//若至少其中一侧不存在子节点。
if(root.left == null || root.right == null){
return Math.max(left,right) + 1;
}
return Math.min(left ,right) + 1;
}
}
- 代码2:自底向上。
- 思路:
- 当前节点 root 为空时,说明此处树的高度为 0,0 也是最小值
- 当前节点 root 的左子树和右子树都为空时,说明此处树的高度为 1,1 也是最小值
- 如果为其他情况,则说明当前节点有值,且需要分别计算其左右子树的最小深度,返回最小深度 +1,+1 表示当前节点存在有 1 个深度
class Solution {
//递归深度优先搜索,
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 1;
}
int min_depth = Integer.MAX_VALUE;
if (root.left != null) {
min_depth = Math.min(minDepth(root.left), min_depth);
}
if (root.right != null) {
min_depth = Math.min(minDepth(root.right), min_depth);
}
return min_depth + 1;
}
}
方法2:广度优先遍历
class Solution {
//广度优先遍历
public boolean hasPathSum(TreeNode root, int sum) {
if(root == null){
return false;
}
Deque<TreeNode> nodes = new LinkedList<>();
Deque<Integer> vals = new LinkedList<>();
nodes.offer(root);
vals.offer(root.val);
while(!nodes.isEmpty()){
TreeNode curNode = nodes.poll();
int curVal = vals.poll();
if(curNode.left == null && curNode.right == null){
if(sum == curVal){
return true;
}
continue;
}
if(curNode.left != null){
nodes.offer(curNode.left);
vals.offer(curVal + curNode.left.val);
}
if(curNode.right != null){
nodes.offer(curNode.right);
vals.offer(curVal + curNode.right.val);
}
}
return false;
}
}
226.翻转二叉树
方法1:广度优先遍历,
- 由上到下。依次翻转根节点的左节点与右节点。
class Solution {
//广度优先遍历
public TreeNode invertTree(TreeNode root) {
if(root == null){
return root;
}
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
while(!deque.isEmpty()){
int len = deque.size();
for(int i = 0 ; i < len ; i++){
TreeNode cur = deque.poll();
//翻转左右节点
TreeNode temp = cur.left;
cur.left = cur.right;
cur.right = temp;
//压入队列,依次进行
if(cur.left != null){
deque.offer(cur.left);
}
if(cur.right != null){
deque.offer(cur.right);
}
}
}
return root;
}
}
方法2:递归,由下向上。
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null){
return root;
}
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
101.对称二叉树
方法1:广度优先遍历。
-
一个数对称,应该满足如下条件。因此传入数的根节点,依次通过如下规则判断左右子数是否满足。
如果同时满足下面的条件,两个树互为镜像: * 它们的两个根结点具有相同的值 * 每个树的右子树都与另一个树的左子树镜像对称
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null){
return true;
}
return check(root,root);
}
//将根节点的左右指数
public boolean check(TreeNode root_left,TreeNode root_right){
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root_left);
deque.offer(root_right);
while(!deque.isEmpty()){
TreeNode left = deque.poll();
TreeNode right = deque.poll();
//两个都为空
if(left == null && right == null){
continue;
}
//只有一个为空
if(left == null || right == null){
return false;
}
//两个都不为空
if(left.val == right.val){
deque.offer(left.left);
deque.offer(right.right);
deque.offer(left.right);
deque.offer(right.left);
}else{
return false;
}
}
return true;
}
}
方法2:递归
class Solution {
//递归,深度优先遍历
public boolean isSymmetric(TreeNode root) {
if(root == null){
return true;
}
return check(root,root);
}
public boolean check(TreeNode root_left,TreeNode root_right){
//两个都为空
if(root_left == null && root_right == null){
return true;
}
//只存在一个为空
if(root_left == null || root_right == null){
return false;
}
//两个都不为空,则比较两个的值。若值相等,比较其左右节点。
if(root_left.val == root_right.val){
return check(root_left.left ,root_right.right) && check(root_left.right,root_right.left);
}
return false;
}
}
222.完全二叉树的节点个数
方法1: 广度优先遍历。
class Solution {
//广度优先遍历
public int countNodes(TreeNode root) {
if(root == null){
return 0;
}
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
int depth = 1;
int nodeSize = 0;
while(!deque.isEmpty()){