递归算法
递归算法:指一种通过重复将问题分解为同类的子问题而解决问题的方法。
如何通过递归求出一棵二叉树的最大深度,首先递归算法特别重要的一个部分就是结束条件,那么结束条件怎么定义呢?对于二叉树而言,递归就是不断递归二叉树的左右结点,那么结束条件自然就是当结点为null时
if (root == null) {
return 0;
}
递归还有一个部分就是递归的规律,那么对于求解二叉树最大深度,递归规律是什么呢?我们在每次调用递归函数的时候相当于遍历一个树的结点,那么如何得到最大深度呢?就是在调用递归函数的时候,对于左右子树取一个较大的值,同时+1,相当于每一次调用递归函数便调用自身两次,并取这两次的较大值
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
非递归算法(BFS)
对二叉树进行广度优先遍历,使用一个队列将每个节点加入到队列中,每加完二叉树的一层便加入一个标志,每次出队时对出队的元素进行判断是否是标志元素,如果时标志元素则表示这一层已经遍历完,count++,如果不是标志元素则将左右节点不是null的加入到队列中,依次重复这一步操作
public int maxDepth(TreeNode root) {
int count = 0;
Queue<TreeNode> queue = new LinkedList<>();
// 判断根节点是否为空
if (root != null) {
queue.offer(root); // 入队
queue.offer(null); // 对于根节点这一层设置一个null标志
}
while (!queue.isEmpty()) {
root = queue.poll(); // 出队
if (root == null) { // 如果是null则表示这一层遍历完,深度++
if (!queue.isEmpty()) { // 判断是否是最后一个元素
queue.offer(null); // 如果不是最后一个元素就进行入队操作
}
count++; // 深度+1
} else {
if (root.left != null) {
queue.offer(root.left);
}
if (root.right != null) {
queue.offer(root.right);
}
}
}
return count;
}
为什么队列操作不使用add和remove,而使用offer和poll呢?
- add和offer都是添加一个元素,不同之处在于,如果超出队列的界限时,add会抛出一个异常,而offer会返回false
- remove和poll都是从链表首抽取一个元素,区别在如果链表为空时remove会抛出一个异常,而poll则是返回一个null