程序员面试题目总结--数组(二)【二分查找、找出给定数字出现次数、两个有序整型数组交集、找出数组中唯一的重复元素、判断数组中的数值是否连续相邻】

6、分别用递归和非递归实现二分查找算法

题目:用递归和非递归实现二分查找算法

分析:二分查找法也称为折半查找法,它的思想是每次都与序列的中间元素进行比较,二分查找的一个前提条件是数组是有序的。

/************************************************************************/
/* 非递归方法                                                                     */
/************************************************************************/
int BinarySearch(int a[],int n,int data)
{
	if(a==NULL || n<=0)
		return -1;
	int begin=0;
	int end=n-1;
	while(begin <=end)
	{
		int mid=(begin+end)/2;
		if(a[mid]==data)
			return mid;
		else if(a[mid] > data)
			end=mid-1;
		else
			begin=mid+1;
	}
	return -1;
}

/************************************************************************/
/* 递归方法                                                                     */
/************************************************************************/
int BinarySearchRecursion(int a[],int data, int begin, int end)
{
	if(begin > end)
		return -1;
	int mid=(begin+end)/2;
	if(a[mid]==data)
		return mid;
	else if(a[mid] > data)
		return BinarySearchRecursion(a,data,begin,mid-1);
	else 
		return BinarySearchRecursion(a,data,mid+1,end);
}

int BinarySearch_Recursion(int a[],int n, int data)
{
	if(a==NULL || n<=0)
		return -1;
	return BinarySearchRecursion(a,data,0,n-1);
}

7、在排序数组中,找出给定的数字出现的次数

题目:在有序数组中,找出给定数字的出现次数, 如[1,2,2,2,3]中2出现次数为3.

分析:该问题的解决方法可以在二分查找的基础上进行改进。设数组a为递增序列,需要查找的元素为data,为了求给定数字的出现次数,可以分别寻找data在a中最先出现的位置和最后出现的位置,然后就可求出数字的出现次数。

int BinarySearch(int a[],int n,int data, bool isLeft)
{
	//isLeft标记值是否在左边
	if(a==NULL || n<=0)
		return -1;
	int begin=0;
	int end=n-1;
	int last=-1;
	while(begin <=end)
	{
		int mid=(begin+end)/2;
		if(a[mid] > data)
			end=mid-1;
		else if(a[mid] < data)
			begin=mid+1;
		else
		{
			last=mid;
			if(isLeft)
				end=mid-1;
			else
				begin=mid+1;
		}
	}
	return  last;
}

int main()
{
	int a[]={3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,13,19};
	int len=sizeof(a)/sizeof(a[0]);
	int index1=BinarySearch(a,len,3,true);//求最先出现的位置
	int index2=BinarySearch(a,len,3,false);//求最后出现的位置
	cout << index1 << ' ' << index2 << endl;
	cout << index2-index1+1 << endl;

}
8、计算两个有序整型数组的交集

题目:两个含有n个元素的有序(非降序)整型数组a和b(无重复元素),求出共同元素。 

如:a=0 1 2 3 4  b= 1 3 5 7 9  a和b交集为{1,3}

分析:采用两路归并来遍历两个数组。设两个数组为a[n1] 和 b[n2] 分别从头遍历连个数组。若a[i]==b[i],则记录数据。若a[i]>b[i],则继续向后遍历b,若a[i]<b[i],则继续向后遍历a。直到一个数组遍历结束为止。

int mixed(int a1[],int n1, int a2[], int n2, int *m)
{
	int i=0,j=0,k=0;
	while(i<n1 && j <n2)
	{
		if(a1[i]==a2[j])
		{
			m[k++]=a1[i];
			i++;
			j++;
		}
		else if(a1[i]<a2[j])
			i++;
		else
			j++;
	}
	return k;
}
9、找出数组中唯一的重复元素

题目:数组a[n],1至n-1这n-1个数存放在a[n]中,其中有一个数重复一次,找出这个重复的数,要求每个数组元素只能访问一次,不用辅助存储空间

分析:由于要求每个元素只能访问一次,可以采用数学求和法。因为只有一个元素重复一次,数也是连续的。对数组的所有项求和,然后减去1至n-1的和,即为重复数。

int FindDup(int a[], int n)
{
	int sum1=0;
	int sum2=0;
	for(int i=0;i<n-1;i++)
	{
		sum1 +=(i+1);
		sum2 +=a[i];
	}
	sum2 +=a[n-1];
	return sum2-sum1;
	
}
10、判断一个数组中的数值是否连续相邻

题目:一个整数数列,元素取值可能是0-65535中的任意一个数,相同数值不会重复出现,0是例外,可以反复出现,设计一个算法,当从该数列中随意选取5个数值时,判断这5个数值是否连续相邻。需要注意一下4点:

       1、5个数值允许乱序 如 87 5 0 6

       2、0可以通配任意数值,如8 7 5 0 6 中的0可以通配成9或4

       3、0可以多次出现

       4、全0算连续,只有一个非0算连续

分析:如果没有0的存在,要组成连续的数列,最大值和最小值的差距必须为4存在0的情况下,只要最大值和最小值的差距小于4就可以了,所以找出数列中非0的最大值和非0的最小值,如果非0最大值-非0最小值+1 <=5 则连续相邻。否则不连续相邻

bool isContinuous(int a[],int n)
{
	int min=-1,max=-1;
	for(int i=0;i<n;i++)
	{
		if(a[i]!=0)
		{
			if(min > a[i] || -1==min)
				min=a[i];
			if(max < a[i] || -1==max)
				max=a[i];
		}
	}
	if(max-min > n-1)
		return false;
	else
		return true;
}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值