百度面试题目分享

来源:互联网 发布:数据库bi是什么 编辑:程序博客网 时间:2024/04/30 04:00

最近在csdn上看到一个百度试题,解题思路很不错,在这里记录下。

题目如下:有这样一个数组,除其中一个元素(如下面的99),其它的都是成对出现的,如何能快速找出那99的位置
……102,102,2,2,44,44,99,23,23,11,11 ……

由于相同元素是相邻出现的,也就为折半查找提供了方便。

通过折半查找,可以不断地缩小单独出现的元素所在的位置,直至最后捕获到该元素。

具体的解题思路如下:

假设该数组元素数量为(n+1)个,从0开始标记,第一个元素为0,最后一个元素为n,数组为array[n];

数组左起点left = 0,右终点right = n,数组中点位置为mid = n/2。

由于为成对出现,所以该数组数量一定为奇数。

若mid为偶数,则mid左右两侧元素个数一定为偶数。若array[mid]与左侧元素相等,则单独元素一定在右半段数组中;

若与右侧元素相等,则单独元素一定在左半段数组中;若都不相等,则array[mid]为单独元素,返回mid。

若mid为奇数,则mid左右两侧元素个数一定为奇数。若array[mid]与左侧元素相等,则单独元素一定在左半段数组中;

若与右侧元素相等,则单独元素一定在右半段数组中;若都不相等,则array[mid]为单独元素,返回mid。

然后根据这种思想,依次递归或是进行while循环修改left和right值即可。

具体代码如下:

#include <stdio.h>int find(int array[], int left, int right){int mid = (left + right)/2;if(mid%2 != 0){if(array[mid] == array[mid+1]){find(array, left, mid-1);}else if(array[mid] == array[mid-1]){find(array, mid+1, right);}else{return mid;}}else{if(array[mid] == array[mid+1]){find(array, mid+1, right);}else if(array[mid] == array[mid-1]){find(array, left, mid-1);}else{return mid;}}}int main(){int array[13] = {6,1,1,2,2,3,3,4,4,7,7,8,8};int num = sizeof(array)/sizeof(int);int left = 0;int right = num - 1;printf("the position is %d\n", (find(array, left, right) + 1));return 0;}

这种方法只适合于相同元素相邻出现的数组,而且不能连续出现两次,像乱序或是{1,1,1,1,3}这种是不适合这种方法的。

乱序的情况可以考虑用异或的方法先找出单独元素,在进行查找。