剑指offer-树(JavaScript)

时间:2021-07-05 16:53:16   收藏:0   阅读:0

7. 重建二叉树

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

    3
   /   9  20
    /     15   7

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {number[]} preorder
 * @param {number[]} inorder
 * @return {TreeNode}
 */
var buildTree = function(preorder, inorder) {
    if(preorder.length==0 || inorder.length==0) return null;
    var root=preorder[0];
    var index = inorder.indexOf(root);
    var left = inorder.slice(0, index);
    var right = inorder.slice(index+1);
    var node = new TreeNode(root);
    node.left = buildTree(preorder.slice(1,index+1), left);
    node.right = buildTree(preorder.slice(index+1), right);
    return node;
};

8. 二叉树的下一个节点

题目描述

给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。下图为一棵有9个节点的二叉树。树中从父节点指向子节点的指针用实线表示,从子节点指向父节点的用虚线表示。

技术图片

例如

输入:{8,6,10,5,7,9,11},8
返回:9
解析:这个组装传入的子树根节点,其实就是整颗树,中序遍历{5,6,7,8,9,10,11},根节点8的下一个节点就是9,应该返回{9,10,11},后台只打印子树的下一个节点,所以只会打印9,如下图,其实都有指向左右孩子的指针,还有指向父节点的指针,下图没有画出来

技术图片

代码

/*function TreeLinkNode(x){
    this.val = x;
    this.left = null;
    this.right = null;
    this.next = null;
}*/

function GetNext(pNode) {
  // write code here
  if (pNode === null) return null; //空结点
  var p = null;
  if (pNode.right) {
    //有右子树,则下一个结点在右子树最左边的结点
    p = pNode.right;
    while (p.left !== null) {
      p = p.left;
    }
    return p;
  } else {
    //没有右子树
    p = pNode.next;
    if (p && p.right === pNode) {
      while (p.next && p.next.right === p) {
        p = p.next;
      }
      p = p.next;
    }
    return p;
  }
  return null;
}

26. 树的子结构

题目描述

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如:
给定的树 A:

     3
    /    4   5
  /  1   2

给定的树 B:

   4 
  /
 1

返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

示例 1:

输入:A = [1,2,3], B = [3,1]
输出:false

示例 2:

输入:A = [3,4,5,1,2], B = [4,1]
输出:true

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} A
 * @param {TreeNode} B
 * @return {boolean}
 */
var isSubStructure = function(A, B) {
    if(!A || !B) return false; 
    return isSame(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
};
var isSame = function(A, B){
    if(!B) return true;
    if(!A) return false;
    if(A.val != B.val) return false;
    return isSame(A.left, B.left) && isSame(A.right, B.right);
}

27.二叉树的镜像

题目描述

请完成一个函数,输入一个二叉树,该函数输出它的镜像。

例如输入:

     4
   /     2     7
 / \   / 1   3 6   9

镜像输出:

	 4
   /     7     2
 / \   / 9   6 3   1

示例 1:

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

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var mirrorTree = function(root) {
    if(!root) return root;
    [root.left, root.right] = [root.right, root.left];
    mirrorTree(root.left);
    mirrorTree(root.right);
    return root
};

28.对称的二叉树

题目描述

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

    1
   /   2   2
 / \ / 3  4 4  3

但是[1,2,2,null,3,null,3] 则不是镜像对称的:

    1
   /   2   2
   \      3    3

示例 1:

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

示例 2:

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

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isSymmetric = function(root) {
    if(!root) return true;
    return isSame(root.left, root.right)
};
var isSame = function(A, B){
    if(!A && !B) return true;
    if(!A) return false;
    if(!B) return false;
    if(A.val != B.val) return false;
    return isSame(A.left, B.right) && isSame(A.right, B.left); 
}

32-I.从上到下打印二叉树

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

例如:

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

   3
  /   9  20
    /     15   7

返回:

[3,9,20,15,7]

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var levelOrder = function(root) {
    if(!root) return [];
    let nodes = [];
    nodes.push(root);
    let res = [];
    while(nodes.length > 0){
        node = nodes.shift();
        res.push(node.val);
        node.left && nodes.push(node.left);
        node.right && nodes.push(node.right);
    }
    return res;
};

32-II.从上到下打印二叉树II

题目描述

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

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

    3
   /   9  20
    /     15   7

返回其层次遍历结果:

[
  [3],
  [9,20],
  [15,7]
]

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
    if(!root) return []
    let nodes = [] // 存放当前节点
    let layer = 0 // 表示当前层数
    let res = []
    nodes.push(root)
    while(nodes.length){
        res[layer] = []
        let num = nodes.length
        while(num--){
            let node = nodes.shift()
            res[layer].push(node.val)
            node.left && nodes.push(node.left)
            node.right && nodes.push(node.right)
        }
        layer++
    }
    return res
};

54. 二叉搜索树的第k大节点

题目描述

给定一棵二叉搜索树,请找出其中第k大的节点。

示例 1:

输入: root = [3,1,4,null,2], k = 1
   3
  /  1   4
     2
输出: 4

示例 2:

输入: root = [5,3,6,2,4,null,null,1], k = 3
       5
      /      3   6
    /    2   4
  /
 1
输出: 4

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} k
 * @return {number}
 */
var kthLargest = function(root, k) {
    let res
    let num = 0
    const dfs = function(root){
        if(root === null){
            return 
        }
        dfs(root.right)
        num++
        if(num === k){
            res = root.val
        }
        dfs(root.left)
    }
    dfs(root)
    return res
};

55-I. 二叉树的深度

题目描述

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。

例如:

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

    3
   /   9  20
    /     15   7

返回它的最大深度 3 。

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
    if(root === null) return 0
    return Math.max(maxDepth(root.left), maxDepth(root.right))+1
};

55-II. 平衡二叉树

题目描述

输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

示例 1:

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

  3
 / \		
 9  20
/  15   7

返回 true 。

代码

function IsBalanced_Solution(pRoot) {
  return depth(pRoot) !== -1;
}

// 用递归来判断root是不是平衡二叉树,如果不是则返回最大的深度,如果不是则返回-1
function depth(root) {
  if (root === null) return 0;
  var left = depth(root.left);
  if (left === -1) return -1;
  var right = depth(root.right);
  if (right === -1) return -1;
  if (Math.abs(left - right) > 1) {
    return -1;
  } else {
    return 1 + Math.max(left, right);
  }
}

68-I. 二叉搜索树的最近公共祖先

题目描述

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

技术图片

示例 :

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {TreeNode}
 */
var lowestCommonAncestor = function(root, p, q) {
    while(root){
        if(root.val<p.val && root.val<q.val){
            root = root.right
        } else if(root.val>p.val && root.val>q.val) {
            root = root.left
        } else {
            break
        }
    }
    return root
};

68-II. 二叉树的最近公共祖先

题目描述

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]

技术图片

示例 1:

输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。```

示例 2:

输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。```

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {TreeNode}
 */
var lowestCommonAncestor = function(root, p, q) {
    if (!root || root === p || root === q) return root;
    const left = lowestCommonAncestor(root.left, p, q);
    const right = lowestCommonAncestor(root.right, p, q);
    // 左子树找不到,返回右子树
    if (!left) return right;
    // 右子树找不到,返回左子树
    if (!right) return left;
    // 左右子树都找到了,那么root就是要找的
    return root;
};
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!