当前位置:   article > 正文

力扣初级——二叉树,解题合集_力扣 二叉树题目

力扣 二叉树题目

1 二叉树的最大深度

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

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

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

示例:

给定二叉树 [3,9,20,null,null,15,7],

    3

   / \

  9  20

    /  \

   15   7

返回它的最大深度 3 。

  解 

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. * @param {TreeNode} root
  11. * @return {number}
  12. */
  13. var maxDepth = function(root) {
  14. return root==null? 0 : Math.max(maxDepth(root.left), maxDepth(root.right))+1;
  15. };

本题比较简单

2验证完全二叉树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左子树只包含 小于 当前节点的数。

节点的右子树只包含 大于 当前节点的数。

所有左子树和右子树自身必须也是二叉搜索树。

也就是说 根节点的val永远大于他左边的,不管到了多少层,隔了多少代

右边同样 永远小于

思路1

本题要注意一点,他说的 “左节点包含的树永远小于root” ,也就是说不管隔了多少代,位于节点左侧的树永远小于根节点的值,基于这一点我们便知道,最左侧的值最小,最右侧的值最大。我们可以将数据收容到同一个数组中,比较数值

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. * @param {TreeNode} root
  11. * @return {boolean}
  12. */
  13. var isValidBST = function(root) {
  14. let res = true
  15. const arr = []
  16. const inorder = (root) => {
  17. if(!root) return
  18. inorder(root.left)
  19. arr.push(root.val)
  20. inorder(root.right)
  21. }
  22. inorder(root)
  23. for(let i = 0; i <arr.length-1; i++) {
  24. if (arr[i] >= arr[i+1] ) {
  25. res = false
  26. break
  27. }
  28. }
  29. return res
  30. // 作者:数据结构和算法
  31. // 链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xn08xg/?discussion=69ga70
  32. // 来源:力扣(LeetCode)
  33. // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

效率很低,1是操作数据次数多,2是可以在遍历中执行的比较放在了for循环内。但是这个解法很直观,也有利于数据后续处理,但单纯做题来说不适用

思路2 递归

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. * @param {TreeNode} root
  11. * @return {boolean}
  12. */
  13. let prev = null
  14. var isValidBST = function(root) {
  15. if (root == null)
  16. return true;
  17. //访问左子树
  18. if (!isValidBST(root.left))
  19. return false;
  20. //访问当前节点:如果当前节点小于等于中序遍历的前一个节点直接返回false。
  21. if (prev != null && prev.val >= root.val)
  22. return false;
  23. prev = root;
  24. //访问右子树
  25. if (!isValidBST(root.right))
  26. return false;
  27. return true;

这个办法是用一个指针标记了他的前一个遍历的节点,中序遍历顺序正好对应了本题数值大小排序,所以只要比较前一个节点是否大于当前节点就可以判断它是不是完全二叉树

这个办法在提交的时候 输入[0]时无法正确作答,但是在单一运行测试时又是对的 ,目前比较困惑

思路3

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. * @param {TreeNode} root
  11. * @return {boolean}
  12. */
  13. let prev = null
  14. var isValidBST = function(root) {
  15. if (root == null)
  16. return true;
  17. //访问左子树
  18. if (!isValidBST(root.left))
  19. return false;
  20. //访问当前节点:如果当前节点小于等于中序遍历的前一个节点直接返回false。
  21. if (prev != null && prev.val >= root.val)
  22. return false;
  23. prev = root;
  24. //访问右子树
  25. if (!isValidBST(root.right))
  26. return false;
  27. return true;

这个办法是层序遍历,当本层元素全部合法时返回true,如果有一个不合法,true值返回链就会被打断,输出false

本题的运行效率也比较高

3对称二叉树

本题比较简单,可以使用上层层序遍历的思想

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. * @param {TreeNode} root
  11. * @return {boolean}
  12. */
  13. var isSymmetric = function (root) {
  14. if (root == null) return true;
  15. const checkRoot = (right, left) => {
  16. if (left == null && right == null) return true;
  17. if (left == null || right == null || left.val != right.val) return false
  18. return checkRoot(right.right, left.left) && checkRoot(right.left, left.right)
  19. }
  20. return checkRoot(root.right, root.left)
  21. };

这个递归的时候要注意,放进去的是L.L,R.R && L.R,R.L

4 二叉树层序遍历

分层输出二叉树,每层单独是一个数组

这个题比较简单,递归不递归都可以做,这里提供一个不递归的做法(上面基本都是递归),很多场景我们可以利用while达到递归的效果,前提是递归的线路不会扩展

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. 不用递归 while循环完成
  11. * @param {TreeNode} root
  12. * @return {number[][]}
  13. */
  14. var levelOrder = function (root) {
  15. const res = []
  16. if (root == null) return []
  17. const temp = []
  18. temp.push(root)
  19. while (temp.length > 0) {
  20. const layerGroup = []
  21. const n = temp.length
  22. for (let i = 0; i < n; i++) {
  23. const target = temp.shift()
  24. layerGroup.push(target.val)
  25. if (target.left != null) {
  26. temp.push(target.left)
  27. }
  28. if (target.right != null) {
  29. temp.push(target.right)
  30. }
  31. }
  32. res.push(layerGroup)
  33. }
  34. return res
  35. };

5.数组转化为高度平衡二叉树

平衡的意思是左侧分支与右侧分支总数量差距小于等于1

我们可以利用层序遍历的方法,先确定一层,然后去确定下一层

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. 二分递归 双指针
  11. * @param {number[]} nums
  12. * @return {TreeNode}
  13. */
  14. var sortedArrayToBST = function (nums) {
  15. if (nums.length == 0) return null
  16. // const root = new TreeNode()
  17. return splitNums(nums,0,nums.length-1)
  18. };
  19. function splitNums(num, start, end){
  20. if (start > end) return null;
  21. let mid = (start + end) >> 1;
  22. let root = new TreeNode(num[mid])
  23. root.left = splitNums(num,start ,mid-1)
  24. root.right = splitNums(num ,mid+1,end)
  25. return root
  26. }

这个解法的重点就是指针,可以看到数组被一直传下去了,由中心指针将数组分为高度平衡的两个数组,所以求中值是必须的,然后将新的开始结尾指针传入下一层

当然说是层序思想,但是分析代码行为我们不难看出这个是先序遍历。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号