您的位置:首页 > 理论基础 > 数据结构算法

精选微软等公司数据结构+算法面试100题带答案(81-85)

2012-09-03 10:34 357 查看
81、第1组百度面试题

1)一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。

分析:有题目知,因为满足条件的a[i],其左边所有的数都小于等于它,右边所有的数都大于等于它,所以该数在数组中相当于已经排好序了。所以我们只需要将排好序的数组与原始数组相比,同一下标对应元素值相同的元素即为所求。

首先,将数组进行排序,结果保存在另外一个数组里面

然后,将原始数组与这个数组比较,所有满足a[i]=b[i] 的数a[i]即为所求

2)一个文件,内含一千万行字符串,每个字符串在1K以内,要求找出所有相反的串对,如abc和cba。

第一轮,计算每一行的hash值

第二轮,计算每一行反转的字符串的hash值,如果此值与第一轮的hash值冲突,则文件中存在该字符串及其反转的字符串

3)STL的set用什么实现的?为什么不用hash?

STL中的set是用红黑树实现的,具有自动排序功能,且set中的元素不能重复,主要用来存储一系列的值,如黑名单。hash更偏向于高效率查找。

82、第2组百度面试题

1)给出两个集合A和B,其中集合A={name},集合B={age、sex、scholarship、address、...},

要求:

问题1、根据集合A中的name查询出集合B中对应的属性信息;

select *from A,B where A.name=B.name

问题2、根据集合B中的属性信息(单个属性,如age<20等),查询出集合A中对应的name。

select A.name from A,B where A.name=B.name AND B.age<20

2)给出一个文件,里面包含两个字段{url、size},即url为网址,size为对应网址访问的次数,

要求:

问题1、利用Linux Shell命令或自己设计算法,查询出url字符串中包含“baidu”子字符串对应的size字段值;

使用hash存储,键用来存储url,键对应的值存储url出现的次数size,url每出现一次,对应的size自加一次。

问题2、根据问题1的查询结果,对其按照size由大到小的排列。(说明:url数据量很大,100亿级以上)

见:/article/7799388.html

83、第3组百度面试题

1)给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。要求:空间复杂度O(1),时间复杂度为O(n)。
void swap(int *a,int i,int j)
{
if(i==j) //相同的数,不做交换
return;
int temp=a[i];
a[i]=a[j];
a[j]=temp;

}

//重新排列数组元素
void ArrayArrange(int *array,int n)
{
int i=0,j=0;

while(i<n&&((array[i]&1)==0)) //跳去偶数,保证i指向奇数
i++;
if (i==n)  //如果全都是偶数,直接返回
return;
swap(array,i++,j++);

while(i<n)
{
if (array[i]&1==1)
swap(array,i,j++); //后面的奇数与前面的偶数交换
i++;
}
}


2)用C语言实现函数void * memmove(void *dest, const void *src, size_t n)。memmove函数的功能是拷贝src所指的内存内容前n个字节到dest所指的地址上。
void memcpy(void *dest, const void *src, size_t len)
{
assert(dest!=NULL&&src!=NULL); //宏断言
const char *pSrc=static_cast<const char*>(src); //类型强制转换
char *pDest=static_cast<char*>(dest);

if(pSrc<pDest&&pSrc+len>pDest) //内存重叠
{
for (size_t i=len-1;i>=0;i--)
{
*(pDest+i)=*(pSrc+i);
}
}

for (size_t i=0;i<len;i++)  //内存无重叠
{
*(pDest+i)=*(pSrc+i);
}
}


84、第4组百度面试题

1)a~z包括大小写与0~9组成的N个数,用最快的方式把其中重复的元素挑出来。

遍历这N个数,以a~z、A~Z、0~9这些数为键,以他们各自出现的次数为值,建立hash表。

查找hash表中值大于1的所有的键值,即为重复的元素。

2)已知一随机发生器,产生0的概率是p,产生1的概率是1-p,现在要你构造一个发生器,使得它构造0和1的概率均为1/2;构造一个发生器,使得它构造1、2、3的概率均为1/3;...,构造一个发生器,使得它构造1、2、3、...n的概率均为1/n,要求复杂度最低。
当p=1/2时,由于需要产生1/2,而用1位0,或1位1无法产生等概率,因此,考虑将随机数扩展成2位:

00 p*p

01 p*(1-p)

10 (1-p)*p

11 (1-p)*(1-p)

有上述分析知道,01和10是等概率的,因此我们只需要产生01和10就行了。于是可以,遇到00和11就丢弃,只记录01和10。可以令,01表示0,10表示1,则等概率1/2产生0和1了。

对n=2,认为01表示0、10表示1,等概率,其他情况放弃
对n=3,认为001表示1、010表示2,100表示3,等概率,其他情况放弃
对n=4,认为0001表示1、0010表示2,0100表示3,1000表示4,等概率,其他情况放弃
首先是1/2的情况,我们一次性生成两个数值,如果是00或者11丢弃,否则留下,01为1,10为0,他们的概率都是p*(1-p)是相等的,所以等概率了。然后是1/n的情况了,我们以5为例,此时我们取x=2,因为C(2x,x)=C(4,2)=6是比5大的最小的x,此时我们就是一次性生成4位二进制,把1出现个数不是2的都丢弃,这时候剩下六个:0011,0101,0110,1001,1010,1100,取最小的5个,即丢弃1100,那么我们对于前5个分别编号1到5,这时候他们的概率都是p*p*(1-p)*(1-p)相等了。

关键是找那个最小的x,使得C(2x,x)>=n这样能提升查找效率

3)有10个文件,每个文件1G,每个文件的每一行都存放的是用户的query,每个文件的query都可能重复。要求按照query的频度排序。

见:/article/7799388.html (大数据处理)

85、又见字符串的问题

1)给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。分析:记住,这种题目往往就是考你对边界的考虑情况。

见:本页83第二小题

2)已知一个字符串,比如asderwsde,寻找其中的一个子字符串比如sde的个数,如果没有返回0,有的话返回子字符串的个数。
kmp算法没看懂,就写个O(n^2)复杂度的吧

int SubstrCount(const char *str,const char *substr)
{
const char *s1=str,*s2=substr;
size_t count=0,k=0;
for (size_t i=0;i<strlen(s1);i++)  //遍历str
{
if (s1[i]==s2[0])
{
for (size_t j=0;j<strlen(s2);j++) //匹配substr
{
if (s1[i+k]!=s2[j])
break;
k++;
}
if (k==strlen(s2)) //匹配成功
{
count++;
k=0;
}
}
k=0;  //更新k
}

return count;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐