代码随想录算法训练营第十五天| 层序遍历(即广度优先搜索), 226.翻转二叉树,101. 对称二叉树

层序遍历(即广度优先搜索)

需要借用一个队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

思路是先把根节点加入队列,然后在遍历下一层前,先将队列拥有的当前层元素加入到结果集中,然后再将当前节点的左节点,右节点加入到队列中


class Solution {
    List> resList=new ArrayList>();
    public List> levelOrder(TreeNode root) {
        checkFun(root);
        return resList;


    }
    //BFS--迭代方式--借助队列
    public void checkFun(TreeNode node){
        if(node==null){return;}
        Queue que=new LinkedList();//借助辅助队列
        que.offer(node);//向队尾插入元素
        while(!que.isEmpty()){
            List itemList=new ArrayList();
            int len=que.size();
            while(len>0){//这里不能是 while(!que.isEmpty()),因为如果是那样子,那么外层while循环就不执行了
                TreeNode tmpNode=que.poll();//拿出队头元素
                itemList.add(tmpNode.val);
                if(tmpNode.left!=null){que.offer(tmpNode.left);}
                if(tmpNode.right!=null){que.offer(tmpNode.right);}
                len--;
            }
            resList.add(itemList);   
        }

    }

}

 226.翻转二叉树

226. 翻转二叉树

解法一BFS  

思路:先将根节点添加到队列中,队列不为空,则计算出队列的长度size,如果size大于0则一直反转当前遍历到的节点的左右树

 //BFS
class Solution {
    public TreeNode invertTree(TreeNode root) {
        //层序遍历吧
        if(root==null){return null;}
        Deque deque=new ArrayDeque<>();
        deque.offer(root);//插入元素到队尾
        while(!deque.isEmpty()){
            int size=deque.size();
            while(size-->0){
                TreeNode node=deque.poll();//移除队头元素
                swap(node);
                if(node.left!=null){deque.offer(node.left);}
                if(node.right!=null){deque.offer(node.right);}
            }
        }
        return root;
    }
    public void swap(TreeNode root){
        TreeNode temp=root.left;
        root.left=root.right;
        root.right=temp;

    }
}

解法二DFS

思路:就是这里注意中序遍历是无法达到反转的要求的,不信可以自己举个例子

采用后序遍历,首先递归将左子树和右子树翻转,最后翻转根节点

//DFS递归
class Solution {
   /**
     * 前后序遍历都可以
     * 中序不行,因为先左孩子交换孩子,再根交换孩子(做完后,右孩子已经变成了原来的左孩子),再右孩子交换孩子(此时其实是对原来的左孩子做交换)
     */
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        invertTree(root.left);
        invertTree(root.right);
        swapChildren(root);
        return root;
    }

    private void swapChildren(TreeNode root) {
        TreeNode tmp = root.left;
        root.left = root.right;
        root.right = tmp;
    }
}

101. 对称二叉树

注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点

思路

比较左节点的外侧和右节点的外侧,比较左节点的里侧和右节点的里侧

代码随想录算法训练营第十五天| 层序遍历(即广度优先搜索), 226.翻转二叉树,101. 对称二叉树_第1张图片

 考虑五种情况

节点为空的情况有:(这是终止条件)

  • 左节点为空,右节点不为空,不对称,return false
  • 左不为空,右为空,不对称 return false
  • 左右都为空,对称,返回true
  • 左右节点不为空,且数值也不相同的情况我们也处理了
  • 第五种情况是都不为空且数值相等
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compare(root.left,root.right);

    }
    boolean compare(TreeNode left,TreeNode right){  //递归函数参数和返回值
       //终止条件们
       if(left==null&&right!=null){return false;}
       if(left!=null&&right==null){return false;}
       if(left==null&&right==null){return true;}
       if(left!=null&&right!=null&&left.val!=right.val){return false;}
       //第五种情况就是非空且数值相同的情况

       //单层递归逻辑
       boolean b1=compare(left.left,right.right);
       boolean b2=compare(left.right,right.left);
       return b1&&b2;
       
    }
}

你可能感兴趣的:(深度优先,算法)