算法训练day11 | php | 102.层序遍历 , 226.翻转二叉树 , 101.对称二叉树 2

一、力扣题102. 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

示例 2:

输入:root = [1]
输出:[[1]]

示例 3:

输入:root = []
输出:[]

提示:

  • 树中节点数目在范围 [0, 2000] 内
  • -1000 <= Node.val <= 1000

        层序遍历符合队列先进先出的特性,适合用队列来实现。先将二叉树的一层放入队列,将这一层的节点从队列中取出放入数组的同时,将这些节点的子节点放入队列,把这一层取光后,队列中存放的就是下一层的节点了。

        此时就需要一个变量来确定每一层的遍历次数。在队列开始将一层的节点取出来之前,先用$size 记录这一层的节点数,然后遍历 $size 次,就把这一层的节点全取出来了。然后 $size 再继续记录下一层的节点数。

        同时每一层的值都要单独用一个数组存放,定义存放一层的值的数组为 $arr , 所以遍历每一层之前都要把 $arr 重新置空。

function levelOrder($root) {
        $queue = new splQueue();
        if($root) $queue->enqueue($root);
        $result = [];

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            $arr = [];
            for($i = 0; $i < $size; $i++) {
                $cur = $queue->dequeue();
                $arr[] = $cur->val;
                if($cur->left) $queue->enqueue($cur->left);
                if($cur->right) $queue->enqueue($cur->right);
            }
            $result[] = $arr;
        }

        return $result;
    }

之后还做了卡哥推荐的其他类似题目,篇幅原因就不在这里放题目内容了:

107.二叉树的层次遍历II

        将以上层序遍历获取到的数组反转一下就可以了

function levelOrderBottom($root) {
        $queue = new splQueue();
        if($root) $queue->enqueue($root);
        $result = [];

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            $arr = [];

            for($i = 0; $i < $size; $i++) {
                $cur = $queue->dequeue();
                $arr[] = $cur->val;
                if($cur->left) $queue->enqueue($cur->left);
                if($cur->right) $queue->enqueue($cur->right);
            }

            $result[] = $arr;
        }

        $result = array_reverse($result);
        return $result;
    }

199.二叉树的右视图:

        层序遍历中把子节点放入队列的顺序改了一下,换成先放入右节点再放入左节点,这样队列中每一层就都是从右到左遍历的值了,直接取第一个值就好。

function rightSideView($root) {
        $queue = new splQueue();
        if($root) $queue->enqueue($root);
        $result = [];

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            $result[] = $queue->bottom()->val;
            for($i = 0; $i < $size; $i++) {
                $cur = $queue->dequeue();
                $arr[] = $cur->val;
                if($cur->right) $queue->enqueue($cur->right);
                if($cur->left) $queue->enqueue($cur->left);
            }
        }

        return $result;
    }

637.二叉树的层平均值

function averageOfLevels($root) {
        $queue = new splQueue();
        if($root) $queue->enqueue($root);
        $result = [];

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            $arr = [];
            for($i = 0; $i < $size; $i++) {
                $cur = $queue->dequeue();
                $arr[] = $cur->val;
                if($cur->left) $queue->enqueue($cur->left);
                if($cur->right) $queue->enqueue($cur->right);
            }
            if($arr) $result[] = round(array_sum($arr) / count($arr), 5);
        }

        return $result;
    }

429.N叉树的层序遍历

function levelOrder($root) {
		$queue = new splQueue();
        if($root) $queue->enqueue($root);
        $result = [];

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            $arr = [];

            for($i = 0; $i < $size; $i++) {
                $cur = $queue->dequeue();
                $arr[] = $cur->val;
                
                for($j = 0; $j < count($cur->children); $j++) {
                    if($cur->children[$j]) {
                        $queue->enqueue($cur->children[$j]);
                    }
                }
            }

            $result[] = $arr;
        }

        return $result;
    }

515.在每个树行中找最大值

function largestValues($root) {
        $queue = new splQueue();
        if($root) $queue->enqueue($root);
        $result = [];

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            $max = PHP_INT_MIN;

            while($size--) {
                $cur = $queue->dequeue();
                if($cur->val > $max)  $max = $cur->val;
                if($cur->left)  $queue->enqueue($cur->left);
                if($cur->right)  $queue->enqueue($cur->right);
            }

            $result[] = $max;
        } 

        return $result;
    }

116.填充每个节点的下一个右侧节点指针

public function connect($root) {
        $queue = new splQueue();
        if($root) $queue->enqueue($root);

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            while($size) {
                $size--;
                $cur = $queue->dequeue();
                if($size) {
                    $cur->next = $queue->bottom();
                }

                if($cur->left) $queue->enqueue($cur->left);
                if($cur->right) $queue->enqueue($cur->right);
            }
        }

        return $root;
    }

104.二叉树的最大深度

111.二叉树的最小深度

以上这两题之后的训练里有,就不放了。

二、力扣题226. 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

示例 2:

输入:root = [2,1,3]
输出:[2,3,1]

示例 3:

输入:root = []
输出:[]

提示:

  • 树中节点数目范围在 [0, 100] 内
  • -100 <= Node.val <= 100

        这道题说到底就是把二叉树里每个节点的左右节点都交换一下,使用前中后序、层序遍历都可以。

方法一:递归法

function invertTree($root) {
        if(!$root) return;
        
        $temp = $root->left;
        $root->left = $root->right;
        $root->right = $temp;

        if($root->left) $this->invertTree($root->left);
        if($root->right) $this->invertTree($root->right);

        return $root;
    }

方法二:迭代法

function invertTree($root) {
        $stack = new splStack();
        if($root) $stack->push($root);

        while(!$stack->isEmpty()) {
            $cur = $stack->pop();
            $temp = $cur->left;
            $cur->left = $cur->right;
            $cur->right = $temp;

            if($cur->left) $stack->push($cur->left);
            if($cur->right) $stack->push($cur->right);
        }

        return $root;
    }

方法三:层序遍历

function invertTree($root) {
        $queue = new splQueue();
        if($root) $queue->enqueue($root);

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            while($size--) {
                $cur = $queue->dequeue();
                $temp = $cur->left;
                $cur->left = $cur->right;
                $cur->right = $temp;

                if($cur->left) $queue->enqueue($cur->left);
                if($cur->right) $queue->enqueue($cur->right);
            }
        }
        return $root;
    }

三、力扣题101. 对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:

 
 

示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false

提示:

  • 树中节点数目在范围 [1, 1000] 内
  • -100 <= Node.val <= 100

         这道题一开始想不到解法,不知道怎么才能把左子树和右子树的节点一一对应对比。然后去看了题解,才知道了成对对比的方法,就是  left -> left  和  right -> right 对应, left  -> right 和 right -> left 对应。

        递归的话就是分别传入这两对参数到两个递归函数里,然后拿到返回值确定真假。

方法一:递归法

function isSymmetric($root) {
        return $this->result($root->left, $root->right);
    }

    function result($left, $right) {
        if(!$left && !$right) {
            return true;
        } else if(!$left || !$right) {
            return false;
        } else if($left->val != $right->val) {
            return false;
        }

        $leftRes = $this->result($left->left, $right->right);
        $rightRes = $this->result($left->right, $right->left);
        
        return $leftRes && $rightRes;
    }

方法二:迭代法

        使用栈的话就每次把成对的参数放一起入栈,出栈时出两个一起对比就可以了。

function isSymmetric($root) {
        $stack = new splStack();
        $stack->push($root->left);
        $stack->push($root->right);

        while(!$stack->isEmpty()) {
            $right = $stack->pop();
            $left = $stack->pop();

            if($right === null && $left === null) continue;
            if($right === null || $left === null) return false;
            if($right->val != $left->val) return false;

            $stack->push($left->left);
            $stack->push($right->right);
            $stack->push($left->right);
            $stack->push($right->left);
        }

        return true;
    }

方法三:层序遍历

        层序遍历也是同样的逻辑,将成对的参数放入队列,再成对取出对比。

function isSymmetric($root) {
        $queue = new splQueue();
        $queue->enqueue($root->left);
        $queue->enqueue($root->right);

        while(!$queue->isEmpty()) {
            $left = $queue->dequeue();
            $right = $queue->dequeue();

            if($left === null && $right === null) continue;
            if($left === null || $right === null || $left->val != $right->val) return false;
            $queue->enqueue($left->left);
            $queue->enqueue($right->right);
            $queue->enqueue($left->right);
            $queue->enqueue($right->left);
        }

        return true;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值