2018-12-04 - 你真的会二分搜索吗?

问题:请编写一个程序,输入包含 n 个整数的数列 S 以及包含 q 个不重复整数的数列 T,输出即包含于 T 也包含于 S 的整数的个数 C。
输入:第一行输入 n,第二行输入代表 S 的 n 个整数,第三行输入 q,第四行输入代表 T 的 q 个整数。
输出:用一行输出 C。
限制S 的元素按照升序排列。, , S的元素 , T的元素 , 且 T 的元素不重复。
输入示例

5
1 2 3 4 5
3
3 4 1

输出示例

3

解题思路:通过搜索数列 S 中是否包含 T 的各个元素。由于限制条件 “S 的元素按照升序排列”,可以采用二分搜索来解题。

一个可能“正确”的 Solution

#include

int A[1000000], n;

int binary_search(int key){
    int left = 0, right = n, mid;
    while(left < right){
        mid = (left + right) / 2;
        
        // 发现 key
        if(key == A[mid]) return 1;

        // 搜索后半部分
        if(key > A[mid]){
            left = mid + 1;
        }
        // 搜索前半部分
        else if(key < A[mid]){
            right = mid;
        }
    }
    return 0;
}

int main(int argc, char const *argv[])
{

    int q, k, sum = 0;

    scanf("%d", &n);

    for(int i = 0; i < n; i++){
        scanf("%d", &A[i]);
    }

    scanf("%d", &q);

    for(int i = 0; i < q; i++){
        scanf("%d", &k);
        if(binary_search(k)) sum++;
    }

    printf("%d\n", sum);
    
    return 0;
}

仔细看看这行代码,由于 low 和 high 都是整型,当它们的值非常大的时候,low+high 就有可能会溢出,其结果变为一个负数。

mid = (left + right) / 2;

解决方案如下:

mid = left + (right - left) / 2;

你可能感兴趣的:(2018-12-04 - 你真的会二分搜索吗?)