笔试题目见http://blog.csdn.net/hackbuteer1/article/details/8016173
面试题目:
(1) 给定m个数组,每个数组有n个元素,分别有序,要将其归并成一个有序的大数组,并计算时间复杂度。
多路归并 T(m)=2*T(m/2)+O(m*n) => T(m)=mnlog(m)
代码如下
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 const int MaxM=100; 2 const int MaxN=100; 3 int temp1[(MaxM+1)*(MaxN+1)]; 4 int temp2[(MaxM+1)*(MaxN+1)]; 5 const int INFI=1<<30; 6 7 void func(int *p,int n,int low,int mid,int high) 8 { 9 int leftRow = low, leftNum = 0; 10 for (; leftRow<=mid; leftRow++) 11 { 12 for (int j=0; j<n; j++) 13 { 14 temp1[leftNum++] = *(p + leftRow*n + j); 15 } 16 } 17 temp1[leftNum]=INFI; 18 int rightRow = mid+1, rightNum=0; 19 for (; rightRow<=high; rightRow++) 20 { 21 for (int j=0; j<n; j++) 22 { 23 temp2[rightNum++] = *(p + rightRow*n + j); 24 } 25 } 26 temp2[rightNum]=INFI; 27 int i=0, j=0; 28 for (int k=0; k<leftNum+rightNum; k++) 29 { 30 if (temp1[i] <= temp2[j]) 31 { 32 *(p+low*n+k) = temp1[i++]; 33 } 34 else 35 { 36 *(p+low*n+k) = temp2[j++]; 37 } 38 } 39 } 40 41 void UnionSort(int *p,int n,int low,int high) 42 { 43 if (low < high) 44 { 45 int mid = low+(high-low)/2; 46 UnionSort(p,n,low,mid); 47 UnionSort(p,n,mid+1,high); 48 func(p,n,low,mid,high); 49 } 50 } 51 52 int main(void) 53 { 54 int a[4][3] = {{0,2,4},{1,5,7},{2,3,6},{4,8,9}}; 55 int m=4,n=3; 56 UnionSort(a[0],n,0,m-1); 57 for (int i=0; i<m; i++) 58 { 59 for (int j=0; j<n; j++) 60 { 61 cout<<a[i][j] <<" "; 62 } 63 cout<<endl; 64 } 65 return 0; 66 }
(2) 链表的排序
1 用普通链表排序
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 struct Node 2 { 3 int data; 4 Node * next; 5 Node(int _data=0,Node * _next=NULL) 6 { 7 data = _data; 8 next = _next; 9 } 10 }; 11 12 Node * nodeMerge(Node * left, Node * right) 13 { 14 if (left == NULL) 15 { 16 return right; 17 } 18 if (right == NULL) 19 { 20 return left; 21 } 22 Node * ret; 23 if (left->data < right->data) 24 { 25 ret = left; 26 ret->next = nodeMerge(left->next,right); 27 } 28 else 29 { 30 ret = right; 31 ret->next = nodeMerge(left,right->next); 32 } 33 return ret; 34 } 35 36 Node * MergeSort(Node * head) 37 { 38 if(head == NULL || head->next == NULL) 39 { 40 return head; 41 } 42 Node * slow = head, * fast = head; 43 while(fast->next != NULL && fast->next->next != NULL) 44 { 45 fast = fast->next->next; 46 slow = slow->next; 47 } 48 fast = slow->next; 49 slow->next = NULL; 50 slow = head; 51 return nodeMerge(MergeSort(slow),MergeSort(fast)); 52 }
2 要求用C++ 中的stl list排序
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 const int INFI=1<<30; 2 const int MaxNum=1000; 3 int t1[MaxNum]; 4 int t2[MaxNum]; 5 6 void func(list<int>::iterator low,list<int>::iterator mid,list<int>::iterator high) 7 { 8 int cnt1 = 0; 9 mid++; 10 for (list<int>::iterator left = low; left != mid; left++) 11 { 12 t1[cnt1++] = *left; 13 } 14 t1[cnt1] = INFI; 15 int cnt2 = 0; 16 high++; 17 for (list<int>::iterator right = mid; right != high; right++) 18 { 19 t2[cnt2++] = *right; 20 } 21 t2[cnt2] = INFI; 22 int i=0,j=0; 23 for (list<int>::iterator k = low; k != high; k++) 24 { 25 if (t1[i] <= t2[j]) 26 { 27 *k = t1[i]; 28 i++; 29 } 30 else 31 { 32 *k = t2[j]; 33 j++; 34 } 35 } 36 } 37 void UnionSort(list<int>::iterator begin, list<int>::iterator end) 38 { 39 if (begin == end) 40 { 41 return; 42 } 43 int cnt = 0; 44 for (list<int>::iterator it = begin; it != end; it++) 45 { 46 cnt++; 47 } 48 cnt /= 2; 49 list<int>::iterator mid = begin; 50 for (int i=1; i<=cnt; i++) 51 { 52 mid++; 53 } 54 UnionSort(begin,mid); 55 UnionSort(++mid,end); 56 func(begin,--mid,end); 57 }
(3) x轴上有n个点,每个点有一种颜色,共有5种颜色,求包含这5种颜色的点的最短区间范围
此题犹如在一个长字符串中找出其中一段,其中有一个字符集合的所有字符,并且这段字符串要最短,当然,这个长字符串是首位相连的。可以定义一个head和一个tail标识字符串的头和尾。定义一个数组hash[256],用这个数组记录集合中的字符出现的次数,之所以数组大小是256,大概是要用数组下标来标识字符。刚开始head=tail=0,tail++直到字符集合中所有的字符数都不为0为止,然后head++直到字符集合中某个字符的数变为0,这是便得到一个字符段。当tail>=m时,tail=tail%m,当head为m时算法结束.
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 bool isAllIn(char * charSet,int * hash) 2 { 3 for (int i=0; charSet[i]!='\0'; ++i) 4 { 5 if (hash[charSet[i]] == 0) 6 { 7 return false; 8 } 9 } 10 return true; 11 } 12 13 bool findMinLen(char * source,char * charSet,int & begin, int & len) 14 { 15 int sourceLen = strlen(source); 16 int hash[256]; 17 memset(hash,0,sizeof(hash)); 18 int head=0,tail=0; 19 len = 1<<30; 20 while(head < sourceLen) 21 { 22 while(!isAllIn(charSet,hash)) 23 { 24 if (head==0 && tail==sourceLen) 25 { 26 return false; 27 } 28 hash[source[tail%sourceLen]]++; 29 tail++; 30 } 31 while(isAllIn(charSet,hash)) 32 { 33 hash[source[head%sourceLen]]--; 34 head++; 35 } 36 if (tail-head+2 < len) 37 { 38 len = tail-head+1; 39 begin = head-1; 40 } 41 } 42 } 43 44 int main() 45 { 46 char* str = "fuckyouworld!whyamihere."; 47 char* charset = "fu"; 48 49 int begin,length; 50 findMinLen(str,charset,begin,length); 51 52 printf("%d %d\n",begin,length); 53 return 0; 54 }