查找完全二叉树底层的最右节点(一)

是面试的时候问到的题目,没有用很多case去测,不保证代码完全正确

题目

节点结构:

public class TreeNode {
   
    public int val;
    public TreeNode left;
    public TreeNode right;

    public TreeNode(int x) {
   
        val = x;
    }
}

完全二叉树:
叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部

给出完全二叉树,返回底层最右节点的值

解法一:遍历

时间复杂度:n

不管深搜还是广搜,在最差的情况下,都需要遍历所有节点,即时间复杂度为n

深搜

public class DeepestTraverse {
   
		// 记录当前碰到最下边的层的最右节点的值
        private Integer result;
        // result所在的层
        private int resultLevel;

        public int getMostRightBottomNode(TreeNode root) {
   
            deepestTraverse(root, 0);
            return result;
        }

        public void deepestTraverse(TreeNode node, int level) {
   
            if (node.left == null && node.right == null) {
   
                if (result == null) {
   
	            	// 如果是叶子节点并且result还没有初始化,则对result和resultLevel赋值(实际就是初始化根节点的值)
                    result = node.val;
                    resultLevel = level;
                } else if (level > resultLevel) {
   
                	// 如果是叶子节点,并且result已被初始化的情况下,如果当前节点的层级比resultLevel高,则赋值给result和resultlevel(因为每次是先走右节点,因此保证一个层级中,只会记录最右节点)
                    result = node.val;
                    resultLevel = level;
                }
            } else {
   
            	// 每次先走有节点,再走左节点
                if (node.right != null) {
   
                    deepestTraverse(node.right, level + 1);
                }
                if (node.left != null) {
   
                    deepestTraverse(node.left, level + 1);
                }
            }
        }
    }

广搜

public class BreadthTraverse {
   

        public int getMostRightBottomNode(TreeNode root) {
   
            Queue<TreeNode> queue = new LinkedList<>();
            queue.add(root);
            // 记录当前层的满节点的数量
            int levelSize = 1;
            // cursor在当前层走了几个节点
            int cursorIndex = 0;
            // 用于遍历的节点
            TreeNode cursor = null;
            do {
   
                cursor = queue.poll();
                cursorIndex++;
                // 当cursorIndex等于levelSize,代表当前层已经走完,对cursorIndex和levelSize进行设置
                if (cursorIndex == levelSize) {
   
                    cursorIndex = 0;
                    levelSize *= 2;
                }
                // 每次先加左节点,再加右节点,因此cursor保持为遍历过的节点中的最底层的最右节点
                if (cursor.left != null) {
   
                    queue.add(cursor.left);
                }
                if (cursor.right != null) {
   
                    queue.add(cursor.right);
                }
            } while (!queue.isEmpty());
            return cursor.val;
        }
    }

解法二:二分

面试现场,在面试官的努力提醒下,还是没完整的捋出来。。。后面回来捋了捋,即使逻辑上捋顺路, 代码写起来也很复杂啊。。

时间复杂度:logn

  1. 找出最大层数(根据完全二叉树特性,只需要往最左边走即可)
  2. 二分遍历二叉树,简单来说就是把底层所有节点(包含空节点)看成一个数组,对这个数组通过二分的方法进行遍历

以一个4层的二叉树为例:
在这里插入图片描述
以上图为例的步骤:

  1. 检查 底层-下标4 的值((0+8)/2),判断为空,因此目标应该在左边
  2. 检查 底层-下标1 的值((0+3)/2),判断有值,因此目标可能出现在右边或者就
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值