树结构专题

196 阅读2分钟

树结构专题

1.[100] 相同的树

  1. 题目描述
    给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
  2. 题解
  • 递归(深度优先搜索)
    时间复杂度:O(min(m,n))、空间复杂度:O(min(m,n))
    /*
 * @lc app=leetcode.cn id=100 lang=typescript
 *
 * [100] 相同的树
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */
function isSameTree(p: TreeNode | null, q: TreeNode | null): boolean {
    /*
        递归
    */
    if (p == null && q == null) {
        return true;
    }
    if (p == null || q == null) {
        return false;
    }
    if (p.val === q.val) {
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    } else {
        return false;
    }
};
  • 广度优先搜索
    时间复杂度:O(min(m,n))、空间复杂度:O(min(m,n))
  1. 比较两个节点的值,如果两个节点的值不相同则两个二叉树一定不同;
  2. 如果两个节点的值相同,则判断两个节点的子节点是否为空,如果只有一个节点的左子节点为空,或者只有一个节点的右子节点为空,则两个二叉树的结构不同,因此两个二叉树一定不同;
  3. 如果两个节点的子节点的结构相同,则将两个节点的非空子节点分别加入两个队列,子节点加入队列时需要注意顺序,如果左右子节点都不为空,则先加入左子节点,后加入右子节点。
function isSameTree(p: TreeNode | null, q: TreeNode | null): boolean {
    /*
        广度优先
    */
    if (p == null && q == null) {
        return true;
    }
    if (p == null || q == null) {
        return false;
    }
    const queueP: Array<TreeNode> = [];
    const queueQ: Array<TreeNode> = [];
    queueP.push(p);
    queueQ.push(q);
    while (queueP.length > 0 && queueQ.length > 0) {
        let nodeP: TreeNode = queueP.shift();
        let nodeQ: TreeNode = queueQ.shift();
        if (nodeP.val !== nodeQ.val) {
            return false;
        }
        let leftP: TreeNode = nodeP.left,
            rightP: TreeNode = nodeP.right,
            leftQ: TreeNode = nodeQ.left,
            rightQ: TreeNode = nodeQ.right;
        //判断子节点是否同时存在或同时不存在
        if(Number(leftP === null) ^ Number(leftQ === null)){
            return false;
        }
        if(Number(rightP === null) ^ Number(rightQ === null)){
            return false;
        }
        if(leftP !== null){
            queueP.push(leftP);
        }
        if(rightP !== null){
            queueP.push(rightP);
        }
        if(leftQ !== null){
            queueQ.push(leftQ);
        }
        if(rightQ !== null){
            queueQ.push(rightQ);
        }
    }
    //如果同时为空则true
    return queueP.length === 0 && queueQ.length === 0;
};

2.[101] 对称二叉树

  1. 题目描述
    给你一个二叉树的根节点 root , 检查它是否轴对称。
  2. 题解
    1.[100] 相同的树题目类似
  • 递归
    时间复杂度:O(n)、空间复杂度:O(n)
function isSymmetric(root: TreeNode | null): boolean {
    /*
        递归
    */
    const check = (p: TreeNode | null, q: TreeNode | null): boolean => {
        if (p === null && q === null) {
            return true;
        }
        if (p === null || q === null) {
            return false;
        }
        return p.val === q.val
            && check(p.left, q.right)
            && check(p.right, q.left);
    }
    return check(root, root);
}
  • 迭代
    时间复杂度:O(n)、空间复杂度:O(n)
function isSymmetric(root: TreeNode | null): boolean {
    const check = (u: TreeNode | null, v: TreeNode | null): boolean => {
        const queue: (TreeNode | null)[] = [];
        queue.push(u);
        queue.push(v);
        while (queue.length > 0) {
            let nodeP: TreeNode | null = queue.shift();
            let nodeQ: TreeNode | null = queue.shift();
            if (nodeP == null && nodeQ === null) {
                continue;
            }
            if ((nodeP === null || nodeQ === null) || (nodeP.val !== nodeQ.val)) {
                return false;
            }
            queue.push(nodeP.left);
            queue.push(nodeQ.right);

            queue.push(nodeP.right);
            queue.push(nodeQ.left);

        }
        return true;

    };
    return check(root, root);
}