
法一:深度搜索+中序遍历+双指针
思路:通过中序遍历二叉树得到一个递增的数列,再在这个递增的二叉树中找到这两数。
主要学到双指针这个方法。
对于一般数列,我们要找到两数满足其之和等于目标数,我们一般会进行暴力,即两重循环:
for(i=0;i<length;i++){
    for(j=i+1;j<length;j++){
    }
} 
对于暴力,我们要把下图的空白格全都依次检验,贼费时间。

而如果设置双指针,对应 i 和 j ,分别指向数组的头和尾。
如果a[0]+a[7]<target,说明a[0]+a[1],a[0]+a[2],a[0]+a[3],a[0]+a[4].....全都不满足,我们就可以直接把a[0]+的所有数给全部排除。 即把i=0时的那一排全排除了。
如果a[0]+a[7]>target,说明a[1]+a[7],a[2]+a[7],a[3]+a[7]......全不满足,我们就可以把j=7的那一列全排除了。
总结就是 i 是指向数组头的指针,如果i 右移,则删排,j 是指向数组尾的指针,如果j 左移,则删列。
这是缩减搜索空间的思想。
题解参考一张图告诉你 O(n) 的双指针解法的本质原理(C++/Java) - 两数之和 II - 输入有序数组 - 力扣(LeetCode)
代码:
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
void inorderTraversal(const struct TreeNode* node, int* vec, int* pos) {
    if (node == NULL) {
        return;
    }
    inorderTraversal(node->left, vec, pos);
    vec[(*pos)++] = node->val;
    inorderTraversal(node->right, vec, pos);
}
bool findTarget(struct TreeNode* root, int k) {
    int * vec = (int *)malloc(sizeof(int) * 10000);
    int pos = 0;
    inorderTraversal(root, vec, &pos);
    int left = 0, right = pos - 1;
    while (left < right) {
        if (vec[left] + vec[right] == k) {
            return true;
        }
        if (vec[left] + vec[right] < k) {
            left++;
        } else {
            right--;
        }
    }
    free(vec);
    return false;
} 
 
                

















