【八十一题题目合集 微软面试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 阅读(331) 评论(0) 编辑 收藏 举报