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

题目要求:

  问题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代码

#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;
}

 

posted on 2014-11-24 18:41  tractorman  阅读(319)  评论(0编辑  收藏  举报

导航