事遇快意处当转,言遇快意处当住。
1. 题目:二叉树的右视图
说明:以右边的视角来看二叉树,所看到的节点即为答案。
输入: root = [1,2,3,null,5,null,4]
输出: [1,3,4]
1. 最朴素的解法
这里为什么说是最朴素的解法呢?原因在于直接采用了二叉树层次遍历的结论。然后遍历取出每层的最后一个元素即可。
public class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> result = new ArrayList<>();
if(root == null) return result;
List<List<Integer>> levels = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
List<Integer> level = new ArrayList<>();
while(size-- > 0){
TreeNode node = queue.poll();
// 这里采用的是头插法
level.add(0,node.val);
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
levels.add(level);
}
// 取出每层的最右边的元素
for(int i = 0; i < levels.size(); i++){
result.add(levels.get(i).get(0));
}
return result;
}
}
2. 进阶的解法
通过观察层次遍历的过程,我们完全可以在取出队列元素的过程中,找到最右元素
public class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
TreeNode node = queue.poll();
// 当size 为 0时,即表示每层的最右元素
if (size == 0) {
result.add(node.val);
}
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
}
return result;
}
}
3. 取巧的解法
这个解法其实并没有特别之处,只是借助于Deque的方法,可以直接获取到队列的最右边元素。
public class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) return result;
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
int size = deque.size();
// 通过 双端队列(Deque)直接获取最右节点
result.add(deque.peekLast().val);
while (size-- > 0) {
TreeNode node = deque.poll();
if (node.left != null) {
deque.offer(node.left);
}
if (node.right != null) {
deque.offer(node.right);
}
}
}
return result;
}
}
2. 总结
对于这道题目,本质上还是首先要掌握层次遍历的算法。这里只是记录一下自己在做这道题时的思路。