【八十一题题目合集 微软面试100题 第八十一题】

来源:互联网 发布:可变数据打印 编辑:程序博客网 时间:2024/04/29 07:42

题目要求:

  问题1:在一个int数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数。

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

  问题3:STL的set用什么实现的?为什么不用hash?

题目分析:

  问题1分析:

    假设int数组为data[]。

    用两个数组a、b作为辅助数组,a[i]、b[i]分别保存从左到i最大的数和从右到i的最小数,需要遍历两次data。

    然后再遍历一遍原数组data[],将所有的data[i]>=a[i-1]&&data[i]<=b[i]的data[i]找出即可。

    -----改进-------

    不要b数组,初始化a数组之后,直接倒序遍历data{],用一个临时变量min保存到目前为止的最小数,然后找出满足data[i]>=a[i-1]&&data[i]<=min的即可。

    结果:少遍历了一次数组data,少了一个辅助数组b[]。

  问题2分析:

    1000W*1k = 10G.

    根据实际内存,把该文件的数据hash散列到n个小文件file,每个小文件大小大约为10G%n.hash(string)%n = k(其中k∈[0,n),然后把该string放入到file[k]中

    把小文件依次读进内存存入set<string>中,每次读入的字符串倒序后到set<string>中查找,如果有则输出,同时删除set<string>中的该字符串;如果没有则把输入的字符串压入到set<string>中。

  问题3分析:  

   set底层实现方式为RB树(即红黑树),红黑树之后会在博客中专题讲解,主要对红黑树插入和删除用伪码的形式讲解

    首先set,不像map那样是key-value对,它的key与value是相同的。关于set有两种说法,第一个是STL中的set,用的是红黑树;第二个是hash_set,底层用的是hash table。红黑树与hash table最大的不同是,红黑树是有序结构,而hash table不是。但不是说set就不能用hash,如果只是判断set中的元素是否存在,那么hash显然更合适,因为set 的访问操作时间复杂度是log(N)的,而使用hash底层实现的hash_set是近似O(1)的。然而,set应该更加被强调理解为“集合”,而集合所涉及的操作并、交、差等,即STL提供的如交集set_intersection()、并集set_union()、差集set_difference()和对称差集set_symmetric_difference(),都需要进行大量的比较工作,那么使用底层是有序结构的红黑树就十分恰当了,这也是其相对hash结构的优势所在。

代码实现:

问题1代码

</pre><pre name="code" class="cpp">/*
author chengzhuwei
*/
#include <iostream>using namespace std;void Find(int *data,int n);int main(void){    int data[] = {3,2,6,9,8};    Find(data,5);    data[4] = 12;    Find(data,5);    return 0;}void Find(int *data,int n){    if(data==NULL || n<=0)        return ;    int *a = new int[n];    int *b = new int[n];    int max = data[0];    a[0] = data[0];    for(int i = 1;i<n;i++)    {        if(data[i]>max)            max = data[i];        a[i] = max;    }    int min = data[n-1];    b[n-1] = data[n-1];    for(int i = n-2;i>=0;i--)    {        if(data[i]<min)            min = data[i];        b[i] = min;    }        cout << "满足的元素有:";    for(int i = 1;i<n;i++)    {        if(data[i]>=a[i-1] && data[i]<=b[i])            cout << data[i] << " ";    }    cout << endl << "-----------------" << endl;}

问题1改进代码

#include <iostream>using namespace std;void Find(int *data,int n);int main(void){    int data[] = {3,2,6,9,8};    Find(data,5);    data[4] = 12;    Find(data,5);    return 0;}void Find(int *data,int n){    if(data==NULL || n<=0)        return ;    int *a = new int[n];    int *b = new int[n];    int max = data[0];    a[0] = data[0];    for(int i = 1;i<n;i++)    {        if(data[i]>max)            max = data[i];        a[i] = max;    }    int min = data[n-1];        cout << "满足的元素有:";    for(int i = n-1;i>=1;i--)    {        if(data[i]<min)            min = data[i];        if(data[i]>=a[i-1] && data[i]<=min)            cout << data[i] << " ";    }    cout << endl << "-----------------" << endl;}


0 0