来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/recover-binary-search-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。
解答
- 把二叉树转为排序数组
- 从排序数组中找到那两个排序不对的节点
两个节点值替换
/*** Definition for a binary tree node.* function TreeNode(val, left, right) {* this.val = (val===undefined ? 0 : val)* this.left = (left===undefined ? null : left)* this.right = (right===undefined ? null : right)* }*//*** @param {TreeNode} root* @return {void} Do not return anything, modify root in-place instead.*/var recoverTree = function(root) {let nodes = [];function transitionToSortedArray (node, low, high) {if (!node) return null;transitionToSortedArray(node.left, low, node.val);nodes.push(node);transitionToSortedArray(node.right, node.val, high);}transitionToSortedArray(root, -Infinity, Infinity);const sortedNodes = Array.from(nodes).sort((prevNode, node) => prevNode.val - node.val);let toRecoverNodes = [];nodes.forEach((node, i) => {if (node !== sortedNodes[i]) {toRecoverNodes.push(node);}})if (toRecoverNodes.length === 2) {let temp = toRecoverNodes[0].val;toRecoverNodes[0].val = toRecoverNodes[1].val;toRecoverNodes[1].val = temp;}};
优化
优化需要解决一个问题:
如何从数组中找到两个不符合要求的节点?第一个节点出现的条件:当前值比下一个值大,为 null 取当前值
- 第二个节点出现的条件:当前值比下一个值大,取下一个值
```
const inorder = (root, nums) => {
if (root === null) {
} inorder(root.left, nums); nums.push(root.val); inorder(root.right, nums); }return;
const findTwoSwapped = (nums) => { const n = nums.length; let index1 = -1, index2 = -1; for (let i = 0; i < n - 1; ++i) { if (nums[i + 1] < nums[i]) { index2 = i + 1; if (index1 === -1) { index1 = i; } else { break; } } } let x = nums[index1], y = nums[index2]; return [x, y]; }
const recover = (r, count, x, y) => { if (r !== null) { if (r.val === x || r.val === y) { r.val = r.val === x ? y : x; if (—count === 0) { return; } } recover(r.left, count, x, y); recover(r.right, count, x, y); } }
var recoverTree = function(root) { const nums = []; inorder(root, nums); const [first, second] = findTwoSwapped(nums); recover(root, 2, first, second); }; ```
