0
点赞
收藏
分享

微信扫一扫

剑指offer 32Ⅰ.32Ⅱ.32Ⅲ 搜索与回溯算法(简单) 二叉树的BFS

infgrad 2022-02-08 阅读 65

面试题32 - I. 从上到下打印二叉树icon-default.png?t=M0H8https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/

想法:二叉树的层次遍历,借助队列实现,首先将二叉树的头节点放入,再从队列中依次取出节点,若该节点有左右孩子,再将其依次入队.

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int[] levelOrder(TreeNode root) {
        //首先判断是否有根节点,可以省去后续步骤
        if(root == null) 
            return new int[0];
        List<Integer> level= new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();

        //将根节点入队
        queue.add(root);
        //层次遍历二叉树
        while(!queue.isEmpty()){
            //取队首元素
            TreeNode head=queue.poll();
            //加入列表
            level.add(head.val);
            // System.out.println(head.val);
            if(head.left!=null)
                queue.add(head.left);
            if(head.right!=null)
                queue.add(head.right);
        }

        //将列表转为数组
        int[] res = new int[level.size()];
        for(int i = 0;i<level.size();i++){
            res[i] = level.get(i);
        }
        return res;
    }
}

结果:

 

Ⅱ.

剑指 Offer 32 - II. 从上到下打印二叉树 IIicon-default.png?t=M0H8https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/

 

想法:此题与1类似,但需要每一层单独打印,可以将"每一批一起入队的节点"一起打印,即打印子表时,遍历打印"当前"队列长度的所有元素.

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        //首先判断是否有根节点,可以省去后续步骤
        List<List<Integer>> res= new ArrayList<>();
        if(root == null) 
            return res;
        Queue<TreeNode> queue = new LinkedList<>();

        //将根节点入队
        queue.add(root);
        //层次遍历二叉树
        while(!queue.isEmpty()){ 
            List<Integer> level= new ArrayList<>();
            //遍历"此时"队列中的所有元素并"打印"
            for(int i=queue.size();i>0;i--){
                //取队首元素
                TreeNode head=queue.poll();
                //加入列表
                level.add(head.val);
                // System.out.println(head.val);
                if(head.left!=null)
                    queue.add(head.left);
                if(head.right!=null)
                    queue.add(head.right);
            }
            // System.out.println();
            res.add(level);
        }
        return res;
    }
}

结果:

 

Ⅲ.

剑指 Offer 32 - III. 从上到下打印二叉树 IIIicon-default.png?t=M0H8https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/

 

想法: 改题目与Ⅱ相似,考虑使用两个队列,一个存从左到右,一个存从右到左,遍历每层时判断该层序号的奇偶,若为奇数则打印从左到右,否则打印从右到左.

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        //首先判断是否有根节点,可以省去后续步骤
        List<List<Integer>> res= new ArrayList<>();
        if(root == null) 
            return res;
        //从左往右
        Queue<TreeNode> queueLR = new LinkedList<>();
        //从右往左
        Queue<TreeNode> queueRL = new LinkedList<>();

        //将根节点入队
        queueLR.add(root);
        queueRL.add(root);
        //true代表奇数层:从左往右,false代表偶数层:从右往左
        Boolean levelNum=true; 
        //层次遍历二叉树
        while(!queueLR.isEmpty()){ 
            List<Integer> level= new ArrayList<>();
            for(int i=queueLR.size();i>0;i--){
                //取队首元素
                TreeNode headLR=queueLR.poll();
                TreeNode headRL=queueRL.poll();
                //判断奇偶
                if(levelNum)
                    level.add(headLR.val);
                else
                    level.add(headRL.val);
                //从左往右 先放左孩子,后放右孩子
                if(headLR.left!=null)
                    queueLR.add(headLR.left);
                if(headLR.right!=null)
                    queueLR.add(headLR.right);
                //从右往左 先放右孩子,后放左孩子
                if(headRL.right!=null)
                    queueRL.add(headRL.right);
                if(headRL.left!=null)
                    queueRL.add(headRL.left);
            }
            levelNum=!levelNum;
            res.add(level);
        }
        return res;
    }
}

想法二:使用双端队列tmp

代码:

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        List<List<Integer>> res = new ArrayList<>();
        if(root != null) queue.add(root);
        while(!queue.isEmpty()) {
            //tmp 作双端队列使用
            LinkedList<Integer> tmp = new LinkedList<>();
            for(int i = queue.size(); i > 0; i--) {
                TreeNode node = queue.poll();
                //通过结果列表的size判断
                if(res.size() % 2 == 0) 
                    // size为偶数,则当前为奇数层 -> 队列尾部添加,从左往右
                    tmp.addLast(node.val); 
                else 
                    // size为奇数,则当前为偶数层 -> 队列头部添加,从右往左
                    tmp.addFirst(node.val); 
                if(node.left != null) queue.add(node.left);
                if(node.right != null) queue.add(node.right);
            }
            res.add(tmp);
        }
        return res;
    }
}

结果:

 

举报

相关推荐

0 条评论