import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
* ref:https://leetcode-cn.com/problems/binary-tree-right-side-view/
* 给定一个二叉树的根节点root,想象自己站在它的右侧,按照从顶部到底部的顺序,
* 返回从右侧所能看到的节点值。
* 示例 1:
* 输入: [1,2,3,null,5,null,4]
* 输出: [1,3,4]
**/
public class BinaryTreeRightSide {
public static void main(String[] args) {
TreeNode f22right = new TreeNode(4,null,null);
TreeNode f21right = new TreeNode(5,null,null);
TreeNode f1left = new TreeNode(2,null,f21right);
TreeNode f1right = new TreeNode(3,null,f22right);
TreeNode root = new TreeNode(1,f1left,f1right);
System.out.println(iterateRightSideView(root));
System.out.println(recurRightSideView(root));
}
/**
* 分层迭代思想:
* 首先将treeNode的root跟节点添加到线性表中。
* 并设置两个变量:
* currNum用来记录当层节点个数。
* childNum用来记录当前层子层节点个数。
* 然后开始迭代线性表。先迭代root层,计算出currNum和childNum数,
* 并将当前层的左右非空子节点添加到线性表中,同时将当前层最后一个元素记录于结果集。
* 完成一次迭代后,每层的最右侧元素就放入到结果集,并完成下一层元素个数的统计。
* 继续完成下一层迭代,直到线性表中无元素时,结束。
* @param root
* @return
*/
public static List<Integer> iterateRightSideView(TreeNode root) {
List<Integer> result = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList();
queue.offer(root);
// 记录当前层节点个数
int currNum = 1;
// 记录当前层子节点个数
int childNum;
while(!queue.isEmpty()){
// 迭代层级,取出每层最后一个元素
childNum = 0;
for(int i=0;i<currNum;i++){
// 获取一个节点
TreeNode node = queue.poll();
// 添加每层最后一个元素
if(currNum-i==1){
result.add(node.val);
}
// 有左侧子节点
if(node.left!=null){
queue.offer(node.left);
childNum++;
}
// 有右侧子节点
if(node.right!=null){
queue.offer(node.right);
childNum++;
}
}
currNum = childNum;
}
return result;
}
/**
* 递归思想:
* 首先迭代treeNode的所有右节点,当每层的右节点不为空时,加入结果集中。
* 当节点为空时结束。每次在迭代过程中,记录当前的节点是否大于以迭代过的右节点的深度。
* 如果超过,则将右节点(每次迭代过程中,都是采用先右厚左的方式)值记录到结果集中。
* 主要是为了解决树不规则场景,比如左树节点深度是4,右树节点深度是3。这个时候
* 直迭代右节点的话就会少了左树的最后一个节点。
* @param root
* @return
*/
static int totalDeep = 0;
public static List<Integer> recurRightSideView(TreeNode root) {
List<Integer> result = new ArrayList<>();
helper(root,result,1);
return result;
}
/**
* 迭代结束
* @param node
* @param result
* @param deep
*/
private static void helper(TreeNode node, List<Integer> result, int deep) {
if(node==null){
return;
}
if(deep>totalDeep){
totalDeep = deep;
result.add(node.val);
}
// 先右后左
helper(node.right,result,deep+1);
helper(node.left,result,deep+1);
}
}