剑指Offer 32-II.从上到下打印二叉树II
解析过程:
题目要求已经很明确了,我们需要对二叉树进行层序遍历,但这时候要注意返回值是一个嵌套链表,需要对二叉树进行按行打印,所以我们就得找个东西来存放每一行。
队列就是一个比较好的选择了!当根节点不是空的时候,那就将根节点先放入队列。当我们要往list中放的时候就将其取出,然后再将该节点的子节点放入到队列中。我们可以使用for循环来控制每一层的遍历,并且用队列的长度来控制循环。当我们将二叉树遍历完成时那么队列也就一定为空了,所以这可以当做我们BFS的结束条件。
代码实现:
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new LinkedList<>();
if(root != null) queue.add(root);
while(!queue.isEmpty()){
List<Integer> list = new LinkedList<>();
for(int i = queue.size();i > 0;i--){
TreeNode node = queue.remove();
list.add(node.val);
if(node.left != null)queue.add(node.left);
if(node.right != null)queue.add(node.right);
}
res.add(list);
}
return res;
}
}
剑指Offer 32-I.从上到下打印二叉树
题目解析:
其实我挺不明白为什么第一道题,也就是刚才那道题难度被列为简单,而这道题被列为中等,你是不是也很迷惑?
如果刚才那道题你明白了,那么这道题就是小菜一碟,不过要注意,因为我们不知道二叉树中到底有多少个元素,所以我们可以先遍历一遍二叉树,查看其元素个数,再进行层序遍历。也可以像我下面写的这种,先进行层序遍历,将遍历之后的结果放在一个list中,之后再挪到数组中返回。
代码实现:
class Solution {
public int[] levelOrder(TreeNode root) {
if(root == null) return new int[0];
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
List<Integer> arrayList = new ArrayList<>();
while(!queue.isEmpty()){
TreeNode node = queue.remove();
arrayList.add(node.val);
if(node.left != null)queue.add(node.left);
if(node.right != null)queue.add(node.right);
}
int size = arrayList.size();
int[] res = new int[size];
for(int i = 0;i < size;i++){
res[i] = arrayList.get(i);
}
return res;
}
}
剑指Offer 32-III.从上到下打印二叉树III
前提须知:
解析过程:
请注意看上图,如果你对双端队列足够了解,那么这道题就游刃而解了。
很明显,这道题依然是前两道题的变形,那么唯一要注意的就是之字形这个点,可以理解为第一行从左到右打印,第二行从右到左打印,第三行从左到右打印。。。。可得规律奇数行,从左到右,偶数行从右到左,从左到右其实我们已经做出来了,就是队列啊,那从右到左呢?当然是栈啦!双端队列既可以当做队列,也可以当做栈用,所以这个时候我们只要做好标记,当前遍历的是奇数行还是偶数行即可。
双端队列当做队列时,是按照addLast添加元素;当做栈时,按照addFirst添加,元素顺序就是倒序的了。
代码实现:
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new LinkedList<>();
if(root != null) queue.add(root);
int flag = 1;
while(!queue.isEmpty()){
LinkedList<Integer> list = new LinkedList<>();
for(int i = queue.size();i > 0;i--){
TreeNode node = queue.remove();
if(flag % 2 == 1)list.addLast(node.val);
else list.addFirst(node.val);
if(node.left != null)queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
flag++;
res.add(list);
}
return res;
}
}
剑指Offer27.二叉树的镜像
解析过程:
这道题可以使用递归的方式去做,首先整体的思路就是将左子树与右子树交换,直到交换到叶子结点位置,开始返回。
当然也可以配合使用栈或者队列来操作。
代码实现:
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return null;
TreeNode node = root.left;
root.left = mirrorTree(root.right);
root.right = mirrorTree(node);
return root;
}
}
剑指Offer 68-I.二叉搜索树的最近公共祖先
解析过程:
首先要注意两个条件:1.这是一颗二叉搜索树;2.所有节点的值都是唯一的。
这就意味着左孩子一定小于根节点,右孩子一定大于根节点。而现在要判断最近公共祖先,那么也就只有三种情况了
1.如果两个孩子都大于根,那么结果一定在右子树
2.如果两个孩子都小于根,那么结果一定在左子树
3.如果两个孩子分别位于左右子树,或者有一个等于根,那么就找到了。
代码实现:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode cur = root;
while(cur != null){
if(cur.val < p.val && cur.val < q.val){
cur = cur.right;
}else if(cur.val > p.val && cur.val > q.val){
cur = cur.left;
}else{
break;
}
}
return cur;
}
}
注:明天想写一写topK~