leetcode1026题解及感悟

leetcode1026题解及感悟

leetcode1026
由于最近正在学数据结构树的相关内容,所以找了点题目来做,所以话不多说来看题吧

leetcode1026题解及感悟_第1张图片

题目的意思是例如给定你一棵二叉树,我们要找到这棵树中的两个不同的结点A和B,并且满足A是B的祖先,然后在所有满足这种关系的两个结点中,找出两个结点差值的绝对值最大的两个,并返回该最大的差值

下面给出几个例子

leetcode1026题解及感悟_第2张图片
根据上面的二叉树,则有如下这些:
| 7-1 |=6
| 7-2 |=5
| 7-8 |=1
| 7-6 |=1
| 7-4 |=3
| 1-8 |=7
|1- 6 |=5
| 2-4 |=2
则最大值为7,返回7。

刚开始做这题的时候,第一想法是暴力解题法
首先把树中的每一个结点,看作是根节点,再把它的子孙和该根节点看作是一棵子树,然后在通过遍历算法,算出根节点与其下的每一个后代结点差值,再通过比较求出最大值。这样我们就算出了以树中一个结点为根节点的最大差值,然后我们再通过遍历算法,将每一个结点做为根节点算出的最大差值进行比较,就可以得出,这棵树的最大差值
由于用到了双重递归时间的复杂度也比较大,为O(n^2)级别,在效率方面比较低,代码我也就不贴出来了。
第二种方法则就比较简单,一遍递归即可
第二种方法是第一种方法的改进,第一种方法,进行了许多的重复比较。
其实我们认真想一想,对于一个结点而言,我们求这个结点的的最大差值,只需要求出它的祖先结点中的最大与最小值,然后再与自己这个结点的值作差取最大的即可。
我们求祖先结点的最大最小值,只需要在递归的过程中传递下来即可。
可以看看下面的代码

class Solution {
public:
    int maxAncestorDiff(TreeNode* root) {
        int left=diff(root->left,root->val,root->val);
        int right=diff(root->right,root->val,root->val);
        return left>right ? left : right;
    }
    int diff(TreeNode *root,int max,int min){
        if(root==NULL)
            return -1;
        if(root->val>max)//如果该节点比前面的祖先结点中最大要大,则该结点的值,就是下一个结点的祖先结点的最大值。
            max=root->val;
        else if(root->val<min)
            min=root->val;
        int left=diff(root->left,max,min);//通过形参传递将祖先结点中的最大值与最小值传递给下一个结点
        int right=diff(root->right,max,min);
        //在回溯的过程中,进行差值比较,求出最大的差值。
        int maxdiff=abs(max-root->val)>abs(min-root->val)?abs(max-root->val):abs(min-root->val);
        int submax=left>right ? left : right;
        return maxdiff>submax?maxdiff:submax;
    }
};

最后说一下心得体会,以及在本题中的收获吧
以前做递归题目的时候,一直云里雾里的,做的稀里糊涂的,不太明白递归的过程是怎样的,做到这道题的时候,稍微明白了一些,递归的一般分为两个过程,一个是递推过程,一个则是回溯的过程,在递推的过程中当我们往往想把这个函数得到的信息,传递给下一个子函数时,可以通过形参来传递。当我们想要把子函数的信息传递给父函数时则是通过函数树的返回值来得到,这样做到了在两个函数之间数据得传递。
有些时候,我们在利用递归求解问题的时候,可能只需要递归这个过程,也有些问题或许只需要,回溯的过程即可,例如像什么链表的反转之类的。也有些题目,在递推与回溯得过程中都要,例如在本题中,我们需要在递推的过程中求得祖先结点中的最大最小值然后在回溯的过程中求得差值的最大值。
这是本人第一次写博客,可能会有许多的描述的不恰当的地方,或者错误的地方,希望大家多多指出,欢迎大家多多留言评论,共同进步。

你可能感兴趣的:(题解及心得)