leetcode刷题记录(6)

本文记录了LeetCode中关于二叉树的五道题目:1. 二叉树的最大深度;2. 二叉树的层次遍历;3. 有序数组转换为二叉搜索树;4. 平衡二叉树;5. 二叉树的最小深度。通过递归和迭代的方法解析了解题思路和关键点。
摘要由CSDN通过智能技术生成

1.二叉树的最大深度

题目:

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

思路:要得到深度,就要遍历树,高度是一层一层累加的,所以采用递归的办法,逐级的获取高度,如果存在左节点或者右节点则自增1,然后计算下一个节点的深度。

var maxDepth = function(root) {
  if (!root) return 0;
  const a = (root, length) => {
    if (!root.left && !root.right) {
      return length;
    } else if (!root.left) {
      return a(root.right, length + 1);
    } else if (!root.right) {
      return a(root.left, length + 1);
    } else {
      return Math.max(a(root.right, length + 1), a(root.left, length + 1));
    }
  };
  return a(root, 1);
};

问题:判断太多,因为已经判断了当前节点为null的情况,不需要再判断left或者right是否为null了

var maxDepth = function(root) {
  if (!root) return 0;
  return Math.max(maxDepth(root.right), maxDepth(root.left)) + 1;
};

迭代的思路:可以每次都把当前层的节点的子节点丢进一个数组,然后判断这个数组的长度,如果长度大于0则说明有下一层。下一轮循环就遍历这个数组,重复,最后没有子节点时跳出循环

var maxDepth = function(root) {
  if (!root) return 0;
  var v = [root],
    r = [],
    res = 1;
  while (v.length) {
    v.forEach((i) => {
      if (i.left) r.push(i.left);
      if (i.right) r.push(i.right);
    });
    if (r.length) {
      v = r;
      r = [];
      res++;
    } else {
      break;
    }
  }
  return res;
};

2.二叉树的层次遍历

题目:给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

思路:和上一题的循环解法非常像,每次把结果放到最前面即可。

var levelOrderBottom = function(root) {
  if (!root) return [];
  var v = [root],
    r = [];
  while (true) {
    var a = [],
      t = [];
    v.forEach((i) => {
      t.push(i.val);
      if (i.left) {
        a.push(i.left);
      }
      if (i.right) {
        a.push(i.right);
      }
    });
    r.unshift(t);
    if (a.length) {
      v = a;
    } else {
      break;
    }
  }
  return r;
};

3.将有序数组转换为二叉搜索树

题目:

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

思路:分治法,想象一下,每次取中间节点,左边的节点组成一颗子树,放在这个节点的左边,右边的节点组成一颗子树,放在这个节点的右边,然后左右的节点数组递归调用,知道长度小于2。.长度为0时直接返回null,长度为1时返回这个节点。最终就得到了二叉树

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {number[]} nums
 * @return {TreeNode}
 */
var sortedArrayToBST = function(nums) {
  let l = nums.length;
  if (!l) return null;
  if (l === 1) return new TreeNode(nums[0]);

  const middle = Math.floor(l / 2);
  const mn = new TreeNode(nums[middle]);
  mn.left = sortedArrayToBST(nums.slice(0, middle));
  mn.right = sortedArrayToBST(nums.slice(middle + 1));
  return mn;
};

4.平衡二叉树

题目:

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

思路:递归求解,在每次执行函数时,判断某个节点的左右两个子树各自是否高度平衡,然后判断两个子树之间的高度是否只相差1.

  const a = (v) => {
    if (!v) return 0;
    return Math.max(a(v.left), a(v.right)) + 1;
  };
var isBalanced = function(root) {
  if (!root) return true;

  return (
    isBalanced(root.left) &&
    isBalanced(root.right) &&
    Math.abs(a(root.left) - a(root.right)) < 2
  );
};

5.二叉树的最小深度

题目:

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明: 叶子节点是指没有子节点的节点。

思路:这个和之前的一个求最大深度的很像,递归求解即可

var minDepth = function(root) {
if(!root)return 0
if(root.left&&root.right){
return Math.min(minDepth(root.left),minDepth(root.right))+1
}else if(root.left){
    return minDepth(root.left)+1
}else{
     return minDepth(root.right)+1
}
};

循环解法:

var minDepth = function(root) {
  if (!root) return 0;
  let stack = [root];
  let res = 1,
    item;
  while (true) {
    let l = stack.length;
    for (let i = 0; i < l; i++) {
      item = stack.shift();
      if (!item.left && !item.right) {
        return res;
      } else {
        if (item.left) stack.push(item.left);
        if (item.right) stack.push(item.right);
      }
    }
    res++;
  }
};

递归的优化:不需要遍历树的每个节点,只需要在遍历的时候保存之前递归的最小结果,然后在递归过程中如果当前深度已经超过这个值,则直接停止这个子树的递归。

var min = (node, res, currD = 0) => {
  currD++;
  if (currD >= res.v) {
    return;
  }
  if (!node.left && !node.right && currD < res.v) {
    res.v = currD;
  }
  if (node.left) min(node.left, res, currD);
  if (node.right) min(node.right, res, currD);
};
var minDepth = function(root) {
      if (!root) return 0;
  var res = { v: Infinity };
  min(root, res);
  return res.v;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值