代码随想录第15天:● 层序遍历 ● 226.翻转二叉树 ● 101.对称二叉树

102:二叉树的层序遍历

感觉比较像一生二,二生四的原理,每次队列中维持的元素都是一层的所有元素,而每次把队列中的元素出队的同时,也把元素结点的左右结点入队。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> resList = new LinkedList<>();
		if (root==null) {
			return resList;
		}
		Queue<TreeNode> queue = new LinkedList<>();//用来维护每一层的结点队列
		queue.offer(root);//先把根节点入队
		while (!queue.isEmpty()) {//当队列元素不为空的时候
			List<Integer> list = new ArrayList<>();//记录每一层元素的list
			int len = queue.size();//队列长度
			while (len>0) {//遍历队列元素,依次出队
				TreeNode node = queue.poll();//弹出队头元素
				list.add(node.val);//队列元素加入list
				if (node.left!=null) {//同时把该结点的左结点入队
					queue.offer(node.left);
				}
				if (node.right!=null) {//同时把该结点的右结点入队
					queue.offer(node.right);
				}
				len--;
			}
			resList.add(list);
		}
		return resList;
    }
}

107:二叉树的层序遍历||

将102得到的队列进行一次reverse操作即可。

199:二叉树的右视图

把每层的最后一个元素记录下来即可。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> resList = new LinkedList<>();
		if (root==null) {
			return resList;
		}
		Queue<TreeNode> queue = new LinkedList<>();//用来维护每一层的结点队列
		queue.offer(root);//先把根节点入队
		while (!queue.isEmpty()) {//当队列元素不为空的时候
			int len = queue.size();//队列长度
			while (len>0) {//遍历队列元素,依次出队
				TreeNode node = queue.poll();//弹出队头元素
				if (len==1) {
					resList.add(node.val);//队列元素加入list
				}
				if (node.left!=null) {//同时把该结点的左结点入队
					queue.offer(node.left);
				}
				if (node.right!=null) {//同时把该结点的右结点入队
					queue.offer(node.right);
				}
				len--;
			}
		}
		return resList;
    }
}

637:二叉树的层平均值

计算每层的平均值

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
       	List<Double> resList = new LinkedList<>();
		if (root==null) {
			return resList;
		}
		Queue<TreeNode> queue = new LinkedList<>();//用来维护每一层的结点队列
		queue.offer(root);//先把根节点入队
		while (!queue.isEmpty()) {//当队列元素不为空的时候
			int len = queue.size();//队列长度
			int count = len;
			double sum = 0;
			while (len>0) {//遍历队列元素,依次出队
				TreeNode node = queue.poll();//弹出队头元素
				sum += node.val;
				if (node.left!=null) {//同时把该结点的左结点入队
					queue.offer(node.left);
				}
				if (node.right!=null) {//同时把该结点的右结点入队
					queue.offer(node.right);
				}
				len--;
			}
			resList.add(sum/count);
		}
		return resList; 
    }
}

429:n叉树的层序遍历

把n个子结点入队。

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> resList = new LinkedList<>();
		if (root==null) {
			return resList;
		}
		Queue<Node> queue = new LinkedList<>();//用来维护每一层的结点队列
		queue.offer(root);//先把根节点入队
		while (!queue.isEmpty()) {//当队列元素不为空的时候
			List<Integer> list = new ArrayList<>();//记录每一层元素的list
			int len = queue.size();//队列长度
			while (len>0) {//遍历队列元素,依次出队
				Node node = queue.poll();//弹出队头元素
				list.add(node.val);//队列元素加入list
				for (Node n : node.children) {
					queue.offer(n);
				}
				len--;
			}
			resList.add(list);
		}
		return resList;
    }
}

515:在每个树行中找最大值

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> resList = new LinkedList<>();
		if (root==null) {
			return resList;
		}
		Queue<TreeNode> queue = new LinkedList<>();//用来维护每一层的结点队列
		queue.offer(root);//先把根节点入队
		while (!queue.isEmpty()) {//当队列元素不为空的时候
			int len = queue.size();//队列长度
			int max = Integer.MIN_VALUE;
			for (int i = 0; i < len; i++) {
				TreeNode node = queue.poll();//弹出队头元素
				if (node.val>max) {
					max = node.val;
				}
				if (node.left!=null) {//同时把该结点的左结点入队
					queue.offer(node.left);
				}
				if (node.right!=null) {//同时把该结点的右结点入队
					queue.offer(node.right);
				}
			}
			resList.add(max);//max加入list	
		}
		return resList;
    }
}

116:填充每个结点的下一个右侧结点

117:填充每个结点的下一个右侧结点指针||

两道题目代码是一样的,原理类似。

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node() {}
    
    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, Node _left, Node _right, Node _next) {
        val = _val;
        left = _left;
        right = _right;
        next = _next;
    }
};
*/

class Solution {
    public Node connect(Node root) {
            if (root==null) {
			return root;
		}
        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
			int len = queue.size();
			for (int i = 0; i < len; i++) {
				Node node = queue.poll();
				if (i==len-1) {
					node.next = null;
				}else {
					node.next = queue.peek();
				}
				if (node.left!=null) {
					queue.offer(node.left);
				}
				if (node.right!=null) {
					queue.offer(node.right);
				}
			}
		}
        return root;
    }
}

104:二叉树的最大深度

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        int depth = 0;
		if (root == null) {
			return 0;
		}
		Queue<TreeNode> queue = new LinkedList<>();
		queue.offer(root);
		while (!queue.isEmpty()) {
			int len = queue.size();
			for (int i = 0; i < len; i++) {
				TreeNode node = queue.poll();
				if (node.left != null) {
					queue.offer(node.left);
				}
				if (node.right != null) {
					queue.offer(node.right);
				}
			}
			depth++;
		}
		return depth;
    }
}

111:二叉树的最小深度

需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int minDepth(TreeNode root) {
    	int depth = 0;
		if (root == null) {
			return 0;
		}
		Queue<TreeNode> queue = new LinkedList<>();
		queue.offer(root);
		while (!queue.isEmpty()) {
			int len = queue.size();
			for (int i = 0; i < len; i++) {
				TreeNode node = queue.poll();
				if (node.left != null) {
					queue.offer(node.left);
				}
				if (node.right != null) {
					queue.offer(node.right);
				}
				if ((node.left==null)&&(node.right==null)) {
					return depth+1;
				}
			}
			depth++;
		}
		return depth;
    }
}

226:翻转二叉树

前序遍历或者后序遍历并进行结点交换。

把遍历和要做的操作分开考虑,不容易混乱。

递归法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
			return root;
		}
		swap(root);
		invertTree(root.left);
		invertTree(root.right);
		return root;
    }
    public void swap(TreeNode root) {
		TreeNode tempNode = root.left;
		root.left = root.right;
		root.right = tempNode;
	}
}

迭代法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
      if (root == null) {
			return root;
		}
		Stack<TreeNode> stack = new Stack<>();
		stack.push(root);
		while (!stack.isEmpty()) {
			TreeNode node = stack.pop();
			swap(node);
			if (node.right!=null) {
				stack.push(node.right);
			}
			if (node.left!=null) {
				stack.push(node.left);
			}
		}
		return root;
    }
    public void swap(TreeNode root) {
		TreeNode tempNode = root.left;
		root.left = root.right;
		root.right = tempNode;
	}
}

层级遍历:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
    	if (root == null) {
			return root;
		}
		Queue<TreeNode> queue = new LinkedList<>();
		queue.offer(root);
		while (!queue.isEmpty()) {
			int len = queue.size();
			for (int i = 0; i < len; i++) {
				TreeNode node = queue.poll();
				swap(node);
				if (node.left != null) {
					queue.offer(node.left);
				}
				if (node.right != null) {
					queue.offer(node.right);
				}
			}
		}
		return root;
    }
    public void swap(TreeNode root) {
		TreeNode tempNode = root.left;
		root.left = root.right;
		root.right = tempNode;
	}
}

101:对称二叉树

“比较的是根节点的两个子树是否是相互翻转的”。

递归法:

1、递归函数:

递归每次返回一个是否对称的结果,因此返回值为boolean。每次比较两个子树是否是相互翻转的,所以参数应该是左子树的头结点和右子树的头结点。boolean judge(TreeNode left, TreeNode right)。

2、递归终止条件:

递归最后肯定是剩下两个结点,由如下情况:

leftrightreturn
null非nullfalse
非nullnullfalse
nullnulltrue
非null,值为val1非null,值为val2false
非null,值为val非null,值为val需要继续递归比较

3、单层递归逻辑

左右节点都不为空,且数值相同的情况需要再次进入单层递归比较:

  • 比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
  • 比较内测是否对称,传入左节点的右孩子,右节点的左孩子。
  • 如果左右都对称就返回true ,有一侧不对称就返回false 。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root==null) {
			return true;
		}
		return judge(root.left, root.right);
    }

    public boolean judge(TreeNode left, TreeNode right) {
		if (left==null && right!=null) {
			return false;
		}else if (left!=null && right==null) {
			return false;
		}else if (left==null && right==null) {
			return true;
		}else if (left.val != right.val) {
			return false;
		}
		boolean outside = judge(left.left, right.right);
		boolean inside = judge(left.right, right.left);
		return outside&&inside;
	}
}

迭代法:

1、用队列

class Solution {
    public boolean isSymmetric(TreeNode root) {
    if (root==null) {
			return true;
		}
		Queue<TreeNode> queue = new LinkedList<>();
		queue.offer(root.left);
		queue.offer(root.right);
		while (!queue.isEmpty()) {
			TreeNode left = queue.poll();
			TreeNode right = queue.poll();
			if (left==null && right==null) {
				continue;
			}
			if (left==null || right==null || left.val != right.val) {
				return false;
			}
			queue.offer(left.left);
			queue.offer(right.right);
			queue.offer(left.right);
			queue.offer(right.left);
		}
		return true;
	}
}

2、栈

class Solution {
    public boolean isSymmetric(TreeNode root) {
    	if (root == null) {
			return true;
		}
		Stack<TreeNode> stack = new Stack<>();
		stack.push(root.left);
		stack.push(root.right);
		while (!stack.isEmpty()) {
			TreeNode right = stack.pop();
			TreeNode left = stack.pop();
			if (left == null && right == null) {
				continue;
			}
			if (left == null || right == null || left.val != right.val) {
				return false;
			}
			stack.push(left.left);
			stack.push(right.right);
			stack.push(left.right);
			stack.push(right.left);
		}
		return true;
	}
}

总结:今天感觉递归更熟练了,但是迭代法写着还是生疏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值