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

来源:互联网 发布:矩阵还有别的意思吗 编辑:程序博客网 时间:2024/04/28 20:35

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亿级以上)

       见:http://blog.csdn.net/dazhong159/article/details/7907174

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表示010表示1,等概率,其他情况放弃

        对n=3,认为001表示1010表示2100表示3,等概率,其他情况放弃

        对n=4,认为0001表示10010表示20100表示31000表示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的频度排序。

       见:http://blog.csdn.net/dazhong159/article/details/7907174  (大数据处理)

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;}
原创粉丝点击