LeetCode刷题日记之二叉树的层序遍历

66 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情
1.二叉树的层序遍历

题目描述

image.png

解题思路

1.二叉树的层序遍历需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
2.使用队列将每一层的节点存起来,同时将下一层节点加入队列中。

var levelOrder = function(root) {
  const queue = [];
  const result = [];
  if(root == null) {
      return []
  }
  queue.push(root)
  while(queue.length) {
      const size = queue.length
      let tmp = []
      for(let i = 0;i<size;i++) {
          const node = queue.shift();
          tmp.push(node.val)
          node.left && queue.push(node.left)
          node.right && queue.push(node.right)

      }
      result.push(tmp)

  }

  return result
};

2.翻转二叉树

题目描述

image.png

解题思路

1.翻转二叉树可以使用递归法,把每个节点的左右节点交换即可。
2.递归三要素:确认递归参数和返回值、确定递归终止条件、确认单层逻辑
3.本题递归参数就是一个节点,返回为左右子树交换后的根节点,当节点为空时返回,单层逻辑为交换传入节点的左右子节点。

var invertTree = function(root) {  
const inverNode=function(left,right){  
let temp=left;  
left=right;  
right=temp;  
//需要重新给root赋值一下  
root.left=left;  
root.right=right;  
}  
//确定递归函数的参数和返回值inverTree=function(root)  
//确定终止条件  
if(root===null){  
return root;  
}  
//确定节点处理逻辑 交换  
inverNode(root.left,root.right);  
invertTree(root.left);  
invertTree(root.right);  
return root;  
};

除此之外,还可以使用迭代法来交换二叉树

var invertTree = function(root) {
    if(root===null){
        return null
    }
    const stack = []
    stack.push(root)
    function swap(root,left,right){
        let temp = left;
        left = right;
        right = temp

        root.left = left
        root.right = right
    }
    while(stack.length){
        const node = stack.pop()
        swap(node,node.left,node.right)


       node.left&& stack.push(node.left)
       node.right&& stack.push(node.right)
    }

    return root
};

3.对称二叉树

题目描述

image.png

解题思路

对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树) ,所以在递归遍历的过程中,也是要同时遍历两棵树。
本题同样采用递归法求解:
1.确认递归参数和返回值,本题需要同时比较左右子树,所以传入的参数是左右子树,返回值为bool值
2.确认递归终止条件,如果左右节点都不为空,若节点值不等返回false;若左空右不空,返回false,左不空右空,返回false,左右节点都为空,返回true
3.确认单层逻辑,比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子;比较内测是否对称,传入左节点的右孩子,右节点的左孩子;如果左右都对称就返回true ,有一侧不对称就返回false 。

var isSymmetric = function(root) {
    
    var compare = function(left,right) {
        if(left == null &&right !== null) { // 左空 右不空
            return false
        } else if(left!==null&&right == null) { // 右空左不空
            return false 
        } else if(left == null&&right==null) { // 左右都空
            return true
        } else if(left.val !== right.val) { // 左右节点不同 剩下的就是左右节点相同情况  继续判断子节点
            return false
        }

        let outside = compare(left.left,right.right)
        let inside = compare(left.right,right.left) // 比较子树的左右测

        return outside && inside // 内外侧都对称才是对的
    }
    
    return compare(root.left,root.right)
};

迭代法

var isSymmetric = function(root) {   
  
// 栈  
if (root === null) return true  
const stack = []  
stack.push(root.left)  
stack.push(root.right)  
while(stack.length){  
const right = stack.pop() // 成对取出  
const left = stack.pop()  
if(left===null&&right===null){  
continue  
}  
if(left === null || right === null||left.val!==right.val){  
return false  
}  
stack.push(left.left) // 成对添加  外侧
stack.push(right.right)  
stack.push(left.right)  // 内侧
stack.push(right.left)  
}  
return true  
};