leetcode 刷题记录 day15

未完成题目(层序遍历题目)】637.二叉树的层平均值、429.N叉树的层序遍历、515.在每个树行中找最大值、116.填充每个节点的下一个右侧节点指针、117.填充每个节点的下一个右侧节点指针II、104.二叉树的最大深度、111.二叉树的最小深度(共七道)。

  • 层序遍历 — 102.二叉树的层序遍历

    思路】层序遍历相当于图论中的广度优先搜索,首先思考如何保存每一层的节点,因为要先进先出(先遍历左子树,并且要返回的顺序也是从左往右),想到要用队列的结构来实现,保存一层的节点并记录节点个数。再依次弹出节点,nums 记录节点,遍历节点的左右子树并把子节点加入到队列中,再把每一层的 nums 记录到最终的二维数组 res中,循环直至节点为空。

    var levelOrder = function(root) {
    	  let res = [], queue = [root];
    	  if (root === null) return res;
    	  while (queue.length) {
    	    let len = queue.length;
    	    let nums = [];  //注意 nums 一定要定义在第一层 while 循环里
    	    
    	    while(len--) {
    	      let node = queue.shift();
    	      if (node !== null) nums.push(node.val);
    	      node.left && queue.push(node.left);
    	      node.right && queue.push(node.right);
    	    }
    	    res.push(nums);
    	  }
    	  return res;
    	};
    
  • 层序遍历 — 107.二叉树的层次遍历II(返回二叉树自底向上的层序遍历)
    思路】返回自底向上的层序遍历遍历就相当于从根节点层序遍历的反转数组。

    var levelOrderBottom = function(root) {
      if (!root) return [];
    
      let queue = [root], res = [];
      while (queue.length) {
        let len = queue.length, curLevel = [];
        while (len--) {
          let node = queue.shift();
          curLevel.push(node.val);
          node.left && queue.push(node.left);
          node.right && queue.push(node.right);
        }
          
        res.unshift(curLevel);  // 倒序添加数组比最后翻转数组更高效,减少运算时间
      }
      return res;
    };
    
  • 层序遍历 — 199.二叉树的右视图
    思路】先开始考虑了 n 种情况:
    1. 首选的是每层右子树的右子树
    2. 当右子树的右子树为空时,选择右子树的左子树
    3. 当右子树的左子树为空时,选择左子树的右子树
    4. 当左子树的右子树为空时,选择左子树的左子树
    开始写的时候发现,虽然想清楚了条件,但是无法判断遍历左子树时右子树是否为空,也就无法确定到底要不要判断左子树,甚至想到了加一个 tag 开关来记录右子树是否为空,从而确定是否判断左子树。
    看了题解才知道规律:每一层添加的是最右边的元素,也就是层序遍历时每一层的最后一个元素。这样清楚的知道了要选择的元素的特征,就正常层序遍历二叉树,每当循环到队列的长度为 0 时,记录当时的节点即可。

    var rightSideView = function(root) {
      if (!root) return [];
    
      let res = [], queue = [root];
      while (queue.length) {
        let len = queue.length;
        while (len--) {
          let node = queue.shift();
          if (len === 0) res.push(node.val);  // 长度为 0 时,证明遍历到了每层的最后一个元素正是我们要的元素
          node.left && queue.push(node.left);
          node.right && queue.push(node.right);
        }
      }
    
      return res;
    };
    
  • 226.翻转二叉树
    思路】递归三部曲🌹!
    未完成】迭代解法(广度和深度两种)

    var invertTree = function(root) {  // 1. 确定参数
      if (!root) return null;  // 2. 确定终止条件
    
    // 3. 确定单次执行逻辑:交换左右子节点
      let leftNode = root.left;
      root.left = invertTree(root.right);
      root.right = invertTree(leftNode);
      return root;  // 1. 确定返回值
    };
    
  • 101.对称二叉树
    思路
    请添加图片描述

    未完成】迭代解法

    var isSymmetric = function(root) {
      const compare = (leftNode, rightNode) => {
        // 确定终止条件:节点为空或者值不相等的情况
        if (leftNode === null && rightNode !== null) return false
        else if (leftNode !== null && rightNode === null) return false
        else if (leftNode === null && rightNode === null) return true
        else if (leftNode.val !== rightNode.val) return false;
    
        // 单次循环执行逻辑
        let outside = compare(leftNode.left, rightNode.right);
        let inside = compare(leftNode.right, rightNode.left);
        return outside && inside;  // 确定返回值
      }
    
      return compare(root.left, root.right);
    };
    

参考代码随想录:https://www.programmercarl.com/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值