代码随想录算法训练营第二十天 | 二叉树

71 阅读3分钟

LeetCode 669. 修剪二叉搜索树

📖 考察点

二叉搜索树的性质

📖 题意理解

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

💡 解题思路

🔑 关键点总结

💻 代码实现

JavaScript

// myself
var trimBST = function (root, low, high) {
	if (!root) return;

	if (root.val < low || root.val > high) {
		// 不在范围内
		if (!root.left && !root.right) {
			// case1 :没有子节点
			return null;
		} else if (!root.left) {
			// case2 :只有单个节点
			return trimBST(root.right, low, high);
		} else if (!root.right) {
			return trimBST(root.left, low, high);
		} else {
			// case3 :2个子节点都存在 ->->-> 根据二叉树的性质,如果不在区间内只需要在另一侧去找符合范围的节点即可,所以不需要合并。
			// 合并两个子节点
			return trimBST(mergeBSTChild(root), low, high);
		}
	} else {
		// 范围内
		root.left = trimBST(root.left, low, high);
		root.right = trimBST(root.right, low, high);
		return root;
	}
};

const mergeBSTChild = (node) => {
	// 左孩子链接在右孩子最左侧 | 相反
	let left = node.left;
	let right = node.right;
	while (right.right) {
		right = right.right;
	}
	right.right = left;
	node.left = null;
	return node.right;
};
// 利用二叉搜索树的性质,省去合并操作
var trimBST = function (root, low, high) {
	if (!root) {
		return null;
	}
	if (root.val < low) {
		return trimBST(root.right, low, high);
	}
	if (root.val > high) {
		return trimBST(root.left, low, high);
	}
	root.left = trimBST(root.left, low, high);
	root.right = trimBST(root.right, low, high);
	return root;
};


⏱️ 复杂度分析

📚 总结与反思


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

📖 考察点

二叉搜索树 平衡二叉树

📖 题意理解

平衡二叉树 是指该树所有节点的左右子树的高度相差不超过 1 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。

💡 解题思路

找到根节点,递归执行

思路一:

思路二:

🔑 关键点总结

💻 代码实现

JavaScript

var sortedArrayToBST = function (nums) {
	if (nums.length === 0) {
		return null;
	}
	if (nums.length === 1) {
		return new TreeNode(nums[0]);
	}
	let index = ~~(nums.length / 2);
	let cur = new TreeNode(nums[index]);
	// 切数组
	let leftNums = nums.slice(0, index);
	let rightNums = nums.slice(index + 1);
	cur.left = sortedArrayToBST(leftNums);
	cur.right = sortedArrayToBST(rightNums);
	return cur;
};

var sortedArrayToBST = function (nums) {
	const buildTree = (Arr, left, right) => {
		if (left > right) return null;

		let mid = Math.floor(left + (right - left) / 2);

		let root = new TreeNode(Arr[mid]);
		root.left = buildTree(Arr, left, mid - 1);
		root.right = buildTree(Arr, mid + 1, right);
		return root;
	};
	return buildTree(nums, 0, nums.length - 1);
};

LeetCode 538.把二叉搜索树转换为累加树

📖 考察点

二叉搜索树 中序便历

📖 题意理解

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

💡 解题思路

采用反向中序便历,记录前一个节点的值,即可更改

🔑 关键点总结

💻 代码实现

JavaScript

// myself
var convertBST = function (root) {
	let cur = root;
	let stack = [];
	if (!root) {
		return null;
	}
	let pre = 0;
	while (stack.length || cur) {
		if (cur) {
			stack.push(cur);
			cur = cur.right;
		} else {
			let node = stack.pop();
			node.val += pre;
			pre = node.val;
			cur = node.left;
		}
	}
	return root;
};