1、阿里巴巴笔试题选解(9月22日,阿里巴巴北邮站)参考链接
题目3、设计一个最优算法来查找一n个元素数组中的最大值和最小值。已知一种需要比较2n次的方法,请给一个更优的算法。情特别注意优化时间复杂度的常数。
代码://思路:将数组分成两两一组,如果数组元素个数为奇数,则剩余的一个自成一组。
//最大元素:Max;
//最小元素:Min;
//分别比较每组中的元素,更新max和min的值。
//总共的比较次数为N/2*3。
//即:总共有N/2组,每组比较三次。组内元素比较一次,然后max跟较大的比较,min跟较小的比较。
const int data[]={4,1,5,9,9,7,10};
int max;
int min;
void grouping(const int data[]){
int len;
int i;
for(i=0;data[i]!='\0';i++);//求数组长度
len=i;
//创建二维数组
int (*group)[2];
group=(int (*)[2])malloc((len+1)*sizeof(int));
//为二维数组赋值
for(int j=0;j
group[j/2][j%2]=data[j];
}
//如果数组有奇数个数
if(len%2!=0)
max=min=group[len/2][0];
else{
if(group[len/2-1][0]>group[len/2-1][1]){
max=group[len/2-1][0];
min=group[len/2-1][1];
}else{
max=group[len/2-1][1];
min=group[len/2-1][0];
}
}
for(int j=0;j
int big;
int small;
if(group[j][0]>group[j][1]){
big=group[j][0];
small=group[j][1];
}else{
big=group[j][1];
small=group[j][0];
}
if(big>max)
max=big;
if(small
min=small;
}
printf("the max data is %d ,the min data is %d !",max,min);
}
int _tmain(int argc, _TCHAR* argv[])
{
grouping(data);
return 0;
}
题目四、
已知三个升序整数数组a[l], b[m]和c[n]。请在三个数组中各找一个元素,是的组成的三元组距离最小。三元组的距离定义是:假设a[i]、b[j]和c[k]是一个三元组,那么距离为:
Distance = max(|a[ I ] – b[ j ]|, |a[ I ] – c[ k ]|, |b[ j ] – c[ k ]|)
思路:
重要公式:max(|a[i]–b[j]|,|a[i]–c[k]|,|b[j]–c[k]|) = (abs(a[i]-b[j])+abs(a[i]-c[k])+abs(b[j]-c[k]))/2
基本思路:用三个指针分别指向a,b,c中最小的数,计算一次他们最大距离的Distance ,然后在移动三个数中较小的数组指针,再计算一次,每次移动一个,直到其中一个数组结束为止,最慢(l+ m + n)次,复杂度为O(l+ m + n)。
代码如下:// Test.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
const int l=3;
const int m=4;
const int n=6;
const int a[l]={5,6,7};
const int b[m]={13,14,15,17};
const int c[n]={19,22,24,29,32,42};
int md;//记录最短距离
int i,j,k;//记录当前数组中正在进行比较的数据下标。
char minArr(int x,int y,int z){
if(x
if(x
return 'a';
else
return 'c';
}
else if(y
return 'b';
}
}
int minDistance(int x,int y,int z){
return (abs(x-y)+abs(y-z)+abs(x-z))/2;
}
void update(char c){
if(c=='a'){
i++;
}
else if(c=='b'){
j++;
}
else
k++;
}
int _tmain(int argc, _TCHAR* argv[])
{
md=minDistance(a[0],b[0],c[0]); //初始化最短距离
int tmp=md;
char arr=minArr(a[0],b[0],c[0]);//arr变量记录当前哪个数组中的值最小。
while(i
update(arr);//更新最小值所在的数组的下标
tmp=minDistance(a[i],b[j],c[k]);//重新计算最短距离,并更新。
if(tmp
md=tmp;
//更新arr为当前哪个数组中的值最小。
arr=minArr(a[i],b[j],c[k]);
}
printf("the min distance is %d",md);
return 0;
}
题目五
考虑奇偶性:1.奇偶 = 奇 -> 1^0 = 12.奇奇 = 偶 -> 1^1 = 03.偶偶 = 偶 -> 0^0 = 0下面就是异或了:把奇数看成1,偶数看成0,这样就是相当于把50个数字看成25个1和25个0。然后考虑到异或的结合律,所以最后得到的数字肯定是25个1和25个0异或的结果,必然是1,也就是奇数