开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 13 天,点击查看活动详情
引言
算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。
题目描述
给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。
示例 1:
输入: root = [1,3,null,null,2]
输出: [3,1,null,null,2]
解释: 3 不能是 1 的左孩子,因为 3 > 1 。交换 1 和 3 使二叉搜索树有效。
示例 2:
输入: root = [3,1,4,null,null,2]
输出: [2,1,4,null,null,3]
解释: 2 不能在 3 的右子树中,因为 2 < 3 。交换 2 和 3 使二叉搜索树有效。
提示:
- 树上节点的数目在范围
[2, 1000]内 -231 <= Node.val <= 231 - 1
分析
注意题目给出的条件,是 二叉搜索树,这就是意味着节点之间是有顺序关系的。 如果我们把整棵树都 遍历 一遍,将遍历的结果保存下来,比如放到一个数组中。 那么这个数组应该是有序的。
既然是有序的那就好办了,我们将这个有序的数组遍历一遍。 如果数组是完全有序的,那么直接返回就可以了。 否则,我们找到顺序不一致的两个下标 i 和 j,将 arr[i].val 和 arr[j].val 的值互换一下即可。
解答
class Solution { public void recoverTree(TreeNode root) { List<TreeNode> list = new ArrayList<TreeNode>(); dfs(root,list); TreeNode x = null; TreeNode y = null; //扫面遍历的结果,找出可能存在错误交换的节点x和y for(int i=0;i<list.size()-1;++i) { if(list.get(i).val>list.get(i+1).val) { y = list.get(i+1); if(x==null) { x = list.get(i); } } } //如果x和y不为空,则交换这两个节点值,恢复二叉搜索树 if(x!=null && y!=null) { int tmp = x.val; x.val = y.val; y.val = tmp; } } //中序遍历二叉树,并将遍历的结果保存到list中 private void dfs(TreeNode node,List<TreeNode> list) { if(node==null) { return; } dfs(node.left,list); list.add(node); dfs(node.right,list); } }
总结
上面的算法思路让我学到了许多知识啊,希望大家继续努力,继续加油啊,加油。哈哈哈哈。