leetcode hard模式专杀之99. Recover Binary Search Tree

这题的思路我还是很快想出来了,奈何二叉树的数据结构和遍历模式不太敏感,代码迟迟没写出来,看来二叉树类的题目需要专项训练一下,补补,下一篇博客我会把二叉树的几种常见算法总结一下。


说思路吧,其实关键就是找到两个交换过的位置就行了,接下来做个交换就行,BST本身如果把它平展开来,就是一个排序序列,例如1,2,3,4,5,6,7,那么这样一个序列假如随机交换两个数会发生什么呢?例如变成1,5,3,4,2,6,7,就是把5和2交换后的样子,如果让你恢复这样一个序列,不要太简单,顺序扫描,发现i比i+1大的情况,就能找到需要交换的位置,这样的位置可能找到两个,也可能只找到一个(两数正好相邻),如果有两个,那么第一个位置的i和第二个位置的i+1,就是交换的index,如果只找到一个,则直接交换i和i+1即可。但是这题要求用空间复杂度constant space的,也就是说不能去建立一个序列再做判断,这个时候就需要技巧了,能不能不通过构建完整序列也能达到同样的效果呢?我开始想了一个方法,尝试写一个next(函数,找到当前节点在序列中的下一个位置),结果尼玛发现不好写,就放弃了,然后就陷入了苦苦的挣扎,最后拖了太久还是看了答案。不说了,上代码,还是挺简洁的:


/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {  
    TreeNode mistake1, mistake2;;  
    TreeNode pre;  
      
    void recursive_traversal(TreeNode root) {  
        if(root==null) {  
            return;  
        }  
        if(root.left!=null) {  
            recursive_traversal(root.left);  
        }  
        if(pre!=null&&root.val

略分析一下这个递归函数 recursive_traversal, 这个函数先递归走左边,再设置pre,再递归走右边,这个非常重要,这样可以保证函数退出时,pre被置为右子节点,而这样递归走下去最终就是设置为right most节点,这个非常重要,因为其实找任意节点的pre位置,思路就是找它的左子树的最右节点。感觉这是一个深度耦合的递归,理解起来其实不是那么直观, 不过的确很有代表性, 需要仔细琢磨一下递归的流程,最好画画图出来,不要表面上感觉自己懂了,但其实漏掉了很多细节

你可能感兴趣的:(leetcode,算法,java)