第二十八题 不管是不是搜索树 用的方法和二十七题一样 都是找公共祖先 (两个方法,第二个暴力破解超过了要求的复杂度)
利用二叉搜索树的性质,判断该点是否处在pq之间
28题自己的答案:
/**
 * struct TreeNode {
 *    int val;
 *    struct TreeNode *left;
 *    struct TreeNode *right;
 *    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @param p int整型 
     * @param q int整型 
     * @return int整型
     */
    int lowestCommonAncestor(TreeNode* root, int p, int q) {
        // write code here
        // 公共结点只可能是 在pq两个数中间,为了方便 让p<q
        // 向下遍历的时候 如果比小的小,显然 pq都大于该节点 公共祖先也用该在右边
        // 同理 如果比大的大 显然pq都小于该节点 公共祖先也在该点的左边
        
        // 让p小,q大
        if(p>q)
        {int temp=p;p=q;q=temp;}
        // pq按照二叉搜索树向下遍历
        while(root!=NULL)
        {
            // 要找的点 应该在pq之间
            if (p <= root->val && q>=root->val )
                return root->val;
            // 该点小于 更小的p,则公共结点必在右边
            else if (p>root->val)
                root=root->right;
            // 该点大于 更大的q,则公共结点必在左边
            else if(q<root->val)
                root=root->left;
        }
        return root->val;
    }
};


27的答案:
/**
 * struct TreeNode {
 *    int val;
 *    struct TreeNode *left;
 *    struct TreeNode *right;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    int findout=0;
    int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
        // 递归找到 从root到指定点的直接路径
        // 因为如果有公共结点 那么这个公共结点到root的路径应该是一样的
        // 所以,找到路径之后,再比对两者的公共路径 直到找到第一个不相同
        
        // write code here
        vector<int>o_1,o_2;
        findout=0;
        // 递归返回o_1 就是从root到o1经过的所有的点
        findpoint(o_1,root, o1);
        // 最后添加一个-1 表示结束了,处理边界问题
        // 用来解决 在最后一个o_1 o_2 较短的最后一个匹配了 的边界问题
        o_1.push_back(-1);
        // 递归调用获得o_2的路径
        findout=0;
        findpoint(o_2,root, o2);
        o_2.push_back(-1);
        
        // 输出o_1、o_2的代码
//         for(int i =0;i<o_1.size();i++)
//         {
//             cout<<o_1[i]<<" ";
//         }
//         cout<<endl;
//         for(int i =0;i<o_2.size();i++)
//         {
//             cout<<o_2[i]<<" ";
//         }
        
        // 因为如果有公共结点 那么这个公共结点到root的路径应该是一样的
        // 所以只要一个个往后比较 出现第一个不一样的时候,返回不一样的值的前一个。
        for(int i =0;i< min(o_1.size(), o_2.size());i++)
        {
            if(o_1[i] != o_2[i] )
                return o_1[i-1];
        }
        return -1;
    }
    
    // 找到到指定数字的路径
    void findpoint(vector<int> &ret_ans,TreeNode* root,int num)
    {
        if(root==NULL)
            return ;
        ret_ans.push_back(root->val);
        if(root->val == num)
        {
            findout=1;
            return;
        }
        // 递归找路径 
        // 如果说已经找到了 直接返回
        findpoint(ret_ans,root->left,num);
        if(findout==1)
            return;
        findpoint(ret_ans,root->right,num);
        if(findout==1)
            return;
        
        // 如果说不是该路径上的点 直接pop扔掉
        ret_ans.pop_back();
        return;
    }
        
};