在leetcode上要到这么一个二叉树的题目,为了解决测试这个题目,写了一些其他的工具函数;并进行了性能优化,效率在leetcode上击败了97%,在这儿记录一下。
方案一
function lowestCommonAncestor1(
root: TreeNode | null,
p: TreeNode | null,
q: TreeNode | null
): TreeNode | null {
if (!root) {
return null;
}
if (p === q) {
return root;
}
if (root === p || root === q) {
if (pIsFatherNodeQ(root, root === p ? q : p)) {
return root;
}
return null;
}
const l = lowestCommonAncestor1(root.left, p, q);
if (l) return l;
const r = lowestCommonAncestor1(root.right, p, q);
if (r) return r;
let x = find(root.left, p, q);
if (!x) return null;
x = x === p ? q : p;
let y = find(root.right, x, x);
if (y) return root;
return null;
function find(root, p, q) {
if (!root) {
return false;
}
if (root === p || root === q) {
return root;
}
return find(root.left, p, q) || find(root.right, p, q);
}
}
优化方案二:
//优化查找最近的公共父节点
function lowestCommonAncestor(
root: TreeNode | null,
p: TreeNode | null,
q: TreeNode | null
) {
function find(root, p, q) {
if (!root) {
return null;
}
if (root === p || root === q) {
if (pIsFatherNodeQ(root, root === p ? q : p)) {
return root; //root是公共父节点,一个是父节点,一个是子节点
}
return { p: root };
}
const l = find(root.left, p, q);
if (l && !l.p) {
return l; //两个都在左子树
}
const r = find(root.right, p, q);
if (r && !r.p) {
return r; //两个都在左子树
}
if (l && r && l?.p !== r?.p) {
return root;
}
return l || r;
}
const res = find(root, p, q);
if (res && !res.p) return res;
return false;
}
其他工具函数
- 树数据结构
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;
}
}
- 查询p是不是q的父节点
//查询p是不是q的父节点
function pIsFatherNodeQ(p, q) {
if (!p) {
return null;
} else {
if (p === q || p.left === q || p.right === q) {
return true;
}
return pIsFatherNodeQ(p.left, q) || pIsFatherNodeQ(p.right, q);
}
}
- 根据层级生成二叉树
//根据层级生成二叉树
function getTree(treeLever = 0) {
let root = new TreeNode(-1);
let i = 0;
function toTreeNode(node, level) {
if (level < treeLever) {
node.left = new TreeNode(i++);
toTreeNode(node.left, level + 1);
node.right = new TreeNode(i++);
toTreeNode(node.right, level + 1);
} else {
return;
}
}
toTreeNode(root, 0);
return root;
}
- 根据数组生成二叉树---层序遍历(根据leetcode生成测试案例数据)
//根据数组生成二叉树---层序遍历
function getTreeByArray(array = []) {
if (!array.length) return null;
let root = new TreeNode(array[0]);
let p = [root];
let t = [];
let i = 1;
while (i < array.length) {
for (let j = 0; j < p.length; j++) {
if (p[j]) {
array[i] ? (p[j].left = new TreeNode(array[i++])) : i++;
array[i] ? (p[j].right = new TreeNode(array[i++])) : i++;
t.push(p[j]?.left || null);
t.push(p[j]?.right || null);
} else {
i += 2;
}
}
p = t;
t = [];
}
return root;
}
- 根据值查询节点
//根据值查询节点
function findNodeBayVal(root, val) {
if (!root) return;
if (root.val === val) {
return root;
} else {
return findNodeBayVal(root.left, val) || findNodeBayVal(root.right, val);
}
}
测试
// const root = getTree(5);
const root = getTreeByArray([1, 2, 3, null, 4]);
const p = findNodeBayVal(root, 4);
const q = findNodeBayVal(root, 3);
const node = lowestCommonAncestor(root, p, q); //3debugger;