笔试题

1. 给定一个如下格式的字符串(1,(2,3),(4,(5,6),7))括号内的元素可以是数字,也可以是另一个括号,请实现一个算法消除嵌套的括号,比如把上面的表达式变成:(1,2,3,4,5,6,7),如果表达式有误请报错。

解:

<span style="font-size:18px;"><span style="font-size:18px;"><pre name="code" class="cpp">void  checkWipe(char *s)
{
static<char> s1;  //正序存放字符串 
static<char> s2;   //存放(
static<char> s3;   //倒序存放字符串 
if(s==NULL)
return;
while(*s!='\0')
{
if(*s=='(')
s2.push();
else if(*s==')')
{
char temp=s2.pop();
if(temp!='(')
{
printf("错误");
return;
}
}else{
s1.push();
}
s++;
}
while(!s1.isEmpty())
{
s2.push(s1.pop());
}
cout<<"(";
while(!s2.isEmpty()) 
{
  cout<<s2.pop();
} 
cout<<")";
}</span></span>
2.A、B两个整数集合,设计一个算法求他们的交集,尽可能的高效。
<span style="font-size:18px;"><span style="font-size:18px;">#include <stdio.h>  
#include <stdlib.h>  
#define M 8  
#define N 5  
int cmp(const void *a, const void *b)  
{  
    int *x = (int *)a;  
    int *y = (int *)b;  
    return (*x) - (*y);  
}  
  
int main(void)  
{  
    int A[] = {-1, 2 ,39 ,10, 6, 11, 188, 10};  
    int B[] = {39 ,8 , 10, 6, -1};  
    //对数组A和数组B进行快排  
    qsort(A, M, sizeof(int), cmp);  
    qsort(B, N, sizeof(int), cmp);  
    //FindIntersection(A, B);  
    int i = 0, j = 0;  
    int cnt = 0;  
    int result[M > N ? M : N];//保存集合的结果  
    //设置i、j索引,分别指向数组A和B,相等则同时移动,不相等则移动较小值的索引  
    while(i < M && j < N)  
    {  
        if(A[i] == B[j])  
        {  
            result[cnt] = A[i];  
            i++;  
            j++;  
            cnt++;  
        }  
        else if(A[i] < B[j])  
        {  
            i++;  
        }  
        else  
        {  
            j++;  
        }  
    }  
    for(i = 0; i < cnt; i++)  
    {  
        printf("%4d", result[i]);  
    }  
    return 0;  
}  </span></span>

3.请设计一个排队系统,能够让每个进入队伍的用户都能看到自己在队中所处的位置和变化。队伍可能随时有人加入和退出,当有人退出影响到用户的位置排名时需要即时反馈到用户。

需要用到设计模式的东西,暂时还未解答!

4.数轴上从左到右有n个点、a[0]    a[1]……、给定一根长度为L的绳子、求绳子最多覆盖其中几个点?

解:

<span style="font-size:18px;"><span style="font-size:18px;">int getMax(int a[],int n,int L)
{
   int temp,max=1;
   int begin=0,end=1;
   while(end<n)
  {
    if(a[end]-a[begin]>L)
    {
      temp=end-begin;
      if(temp>max)
        max=temp;
       begin++;
    }else
   end++; 
  }
  return max;
}</span></span>


5.合并两个排序链表。

<span style="font-size:18px;"><span style="font-size:18px;">List *merge(List *head1,List *head2)
{
if(head1==NULL)
return head2;
if(head2==NULL)
return head1;

List *p1=head1,*p2=head2,*p,*head;

if(p1->data<p2->data)
{
head=p1;
p1=p1->next;
}else{
head=p2;
p2=p2->next;
}
p=head;
while(p1&&p2)
{
if(p1->data<p2->data)
{
p->next=p1;
p1=p1->next;
}else{
p->next=p2;
p2=p2->next;
}
p=p->next;
}

if(p1==NULL)
p->next=p2;
if(p2==NULL)
p->next=p1;

return head;
} </span></span>


6. 一个大文件有100亿个数,乱序排列,求其中位数,内存限制为512M。

解:采用分而治之的策略。

顺序遍历这100亿个数,采用hash(key)%100的策略,将这些数平均的分配到这100个小文件中,然后对每个小文件中的数进行排序,使之有序,然后再对着100个小文件使用归并排序,最后求有序序列的中位数。即序列个数为2n,中位数为第n,n+1;为2n+1,中位数为第n+1个;

7.最长回文子串。

<span style="font-size:18px;"><span style="font-size:18px;">void LongestPalindrome(char *s, int n)  
{  
   int i, j, max,middle=0,begin;
   char *sb;  
   if (s == 0 || n < 1) return 0;  
   max = 0;  
   for (i = 0; i < n; ++i) { // i is the middle point of the palindrome  
       for (j = 0; (i-j >= 0) && (i+j < n); ++j) // if the lengthof the palindrome is odd  
           if (s[i-j] != s[i+j]) break;  
       if (j*2+1 > max) 
       {
           middle=i;
           max = j * 2 + 1;  
       }
       for (j = 0; (i-j >= 0) && (i+j+1 < n); ++j) // for theeven case  
           if (s[i-j] != s[i+j+1]) break;  
       if (j*2+2 > max) 
       {
         max = j * 2 + 2;  
         middle =i;
       }
    }  
         if(max%2==0)
          j=(max-2)/2;
         else
          j=(max-1)/2;
         begin=middle-j;
         
         int k=0;
         while(k<max)
         {
         	cout<<s[begin++];
         	k++;
         }   
}  
</span></span>

8.判断字符串s2是否是s1的子串。

<span style="font-size:18px;"><span style="font-size:18px;">bool isSubString(char *s1,char *s2)
{
    if(s1==NULL || s2==NULL)
	return true;
    int i=0,j=0;
    int n1=strlen(s1);
    int n2=strlen(s2);
    
    while(s1[i]!='\0')
    {
    	if(s2[0]==s1[i])
    	{
    		j=0;
    		int k=i;
    		while(k<n1&&j<n2)
    		{
		    	if(s1[k]!=s2[j])
		    	break;
		    	k++;
		    	j++;
		    }
	    	if(j==n2)
	    	return true;
	    }
	    i++;
    }
    return false;
}</span></span>

9.最长公共子串问题

<span style="font-size:18px;"><span style="font-size:18px;">int LCS(const char *str1  , int len1 , const char *str2 , int len2 , char *&lcs)  
{  
    if(NULL == str1 || NULL == str2)  
    {  
        return -1;  //空参数  
    }  
      
    //  压缩后的最长子串记录向量  
    int *c = new int[len2+1];  
    for(int i = 0 ; i < len2 ; ++i)  
    {  
        c[i] = 0;  
    }  
    int max_len = 0;    //匹配的长度  
    int pos = 0;        //在str2上的匹配最末位置  
    for(int i = 0 ; i < len1 ; ++i)  
    {  
        for(int j = len2 ; j > 0 ; --j)  //更新时从后往前遍历  
        {   
            if(str1[i] == str2[j-1])  
            {  
                c[j] = c[j-1] + 1;  
                if(c[j] > max_len)  
                {  
                    max_len = c[j];  
                    pos = j-1;  
                }  
            }  
            else  
            {  
                c[j] = 0;  
            }  
        }  
    }  
      
    if(0 == max_len)  
    {  
        return 0;  
    }  
      
    //  得到公共子串  
    lcs = new char[max_len];  
    for(int i = 0 ; i < max_len ; ++i)  
    {  
        lcs[i] = str2[pos-max_len+1+i];  
    }  
    cout<<"pos = "<<pos<<endl;  
    delete [] c;  
    return max_len;  
      
}  </span></span>

10.最长公共子序列

<span style="font-size:18px;">/**  
找出两个字符串的最长公共子序列的长度 
** author :liuzhiwei   
** data   :2011-08-15 
**/   
#include "stdio.h"  
#include "string.h"  
#include "stdlib.h"  
int LCSLength(char* str1, char* str2, int **b)  
{  
    int i,j,length1,length2,len;  
    length1 = strlen(str1);  
    length2 = strlen(str2);  
  
    //双指针的方法申请动态二维数组  
    int **c = new int*[length1+1];      //共有length1+1行  
    for(i = 0; i < length1+1; i++)  
        c[i] = new int[length2+1];      //共有length2+1列  
  
    for(i = 0; i < length1+1; i++)  
        c[i][0]=0;        //第0列都初始化为0  
    for(j = 0; j < length2+1; j++)  
        c[0][j]=0;        //第0行都初始化为0  
  
    for(i = 1; i < length1+1; i++)  
    {  
        for(j = 1; j < length2+1; j++)  
        {  
            if(str1[i-1]==str2[j-1])   //由于c[][]的0行0列没有使用,c[][]的第i行元素对应str1的第i-1个元素  
            {  
                c[i][j]=c[i-1][j-1]+1;  
                b[i][j]=0;          //输出公共子串时的搜索方向  
            }  
            else if(c[i-1][j]>c[i][j-1])  
            {  
                c[i][j]=c[i-1][j];  
                b[i][j]=1;  
            }  
            else  
            {  
                c[i][j]=c[i][j-1];  
                b[i][j]=-1;  
            }  
        }  
    }  
    /* 
    for(i= 0; i < length1+1; i++) 
    { 
    for(j = 0; j < length2+1; j++) 
    printf("%d ",c[i][j]); 
    printf("\n"); 
    } 
    */  
    len=c[length1][length2];  
    for(i = 0; i < length1+1; i++)    //释放动态申请的二维数组  
        delete[] c[i];  
    delete[] c;  
    return len;  
}  
void PrintLCS(int **b, char *str1, int i, int j)  
{  
    if(i==0 || j==0)  
        return ;  
    if(b[i][j]==0)  
    {  
        PrintLCS(b, str1, i-1, j-1);   //从后面开始递归,所以要先递归到子串的前面,然后从前往后开始输出子串  
        printf("%c",str1[i-1]);        //c[][]的第i行元素对应str1的第i-1个元素  
    }  
    else if(b[i][j]==1)  
        PrintLCS(b, str1, i-1, j);  
    else  
        PrintLCS(b, str1, i, j-1);  
}  
  
int main(void)  
{  
    char str1[100],str2[100];  
    int i,length1,length2,len;  
    printf("请输入第一个字符串:");  
    gets(str1);  
    printf("请输入第二个字符串:");  
    gets(str2);  
    length1 = strlen(str1);  
    length2 = strlen(str2);  
    //双指针的方法申请动态二维数组  
    int **b = new int*[length1+1];  
    for(i= 0; i < length1+1; i++)  
        b[i] = new int[length2+1];  
    len=LCSLength(str1,str2,b);  
    printf("最长公共子序列的长度为:%d\n",len);  
    printf("最长公共子序列为:");  
    PrintLCS(b,str1,length1,length2);  
    printf("\n");  
    for(i = 0; i < length1+1; i++)    //释放动态申请的二维数组  
        delete[] b[i];  
    delete[] b;  
    system("pause");  
    return 0;  
}  </span>

11.

.

<span style="font-size:18px;"><span style="font-size:18px;">bool isRuledTree(Node *root)
{
	if(root==NULL)
	return true;
	Node *Queue[100],*p;
	int front=0,rear=0;
	int max=1,min=-1;//用来记录叶子节点的最大深度和最小深度。 
	Queue[++rear]=root;
	int level=rear,depth=0;
	while(front<rear)
	{
		p=Queue[++front];
		if(p->lchild!=NULL)
		Queue[++rear]=p->lchild;
		if(p->rchild!=NULL)
		Queue[++rear]=p->rchild;	
		if(level==front)
		{
			depth++;
		    level=rear;	
		}
		if(p->lchild==NULL&&p->rchild==NULL)
		{
			if(min==-1)
			min=depth;
			else
			min=min>depth?depth:min;
			max=max>depth?max:depth;
		}	
	} 
	if(max-min<=1)
	return true;
	else 
	return false;
}
</span></span>

12.字符串的排列与组合

字符串的组合:

//函数功能 : 从一个字符串中选m个元素
 2 //函数参数 : pStr为字符串, m为选的元素个数, result为选中的
 3 //返回值 :   无
 4 void Combination_m(char *pStr, int m, vector<char> &result)
 5 {
 6     if(pStr == NULL || (*pStr == '\0'&& m != 0))
 7         return;
 8     if(m == 0) //递归终止条件
 9     {
10         for(unsigned i = 0; i < result.size(); i++)
11             cout<<result[i];
12         cout<<endl;
13         return;
14     }
15     //选择这个元素
16     result.push_back(*pStr);
17     Combination_m(pStr + 1, m - 1, result);
18     result.pop_back();
19     //不选择这个元素
20     Combination_m(pStr + 1, m, result);
21 }
22 //函数功能 : 求一个字符串的组合
23 //函数参数 : pStr为字符串
24 //返回值 :   无
25 void Combination(char *pStr)
26 {
27     if(pStr == NULL || *pStr == '\0')
28         return;
29     int number = strlen(pStr);
30     for(int i = 1; i <= number; i++)
31     {
32         vector<char> result;
33         Combination_m(pStr, i, result);
34     }
35 }
字符串的排列:

  1.   
  2. void Permutation(char* pStr, char* pBegin)  
  3. {  
  4.     assert(pStr && pBegin);  
  5.   
  6.     if(*pBegin == '\0')  
  7.         printf("%s\n",pStr);  
  8.     else  
  9.     {  
  10.         for(char* pCh = pBegin; *pCh != '\0'; pCh++)  
  11.         {  
  12.             swap(*pBegin,*pCh);  
  13.             Permutation(pStr, pBegin+1);  
  14.             swap(*pBegin,*pCh);  
  15.         }  
  16.     }  
  17. }  

13.有这样一个数组A,大小为n,相邻元素差的绝对值都是1,如A={4,5,6,5,6,7,8,9,10,9},现在给定数组A和目标整数t,请找到t在A中的位置

<span style="font-size:18px;"><span style="font-size:18px;">int find(int A[],int n,int key)
{
	if(A==NULL || n<1)
	return -1; 
	int j=0;    //下标 
	int m;       //偏移量 
	while(1)
	{
		if(A[j]==key)   //找到,返回下标 
			return j;
		m=A[j]-key;	 
		m= m<0?-m:m;
		j=j+m; 
		if (j+m>n-1)     //没有找到,返回-1; 
		{
			return -1;
		} 
	}
}</span></span>

14.判断一棵树是否是二分查找树

思路:二分查找树的中序遍历是有序的,所以可以利用中序遍历来判定树是否是二分查找树

<span style="font-size:18px;">bool check(BTNode *T,int preValue)
{
	if(T==NULL)
	return true;
	if(check(T->lchild,preValue))  //检查左子树是否是二分查找树
	{
		if(T->data>preValue) 
        {
        	preValue=T->data;
        	return check(T->rchild,preValue);  //检查右子树是否是二分查找树
        }
        else
        return false;
	} else
	return false;
}</span>

其中,preValue的初始值为整数的最小值。

详解:http://blog.csdn.net/sgbfblog/article/details/7771096

15.连续子数组的最大和。

<span style="font-size:18px;"> int getSubMax(int data[],int n)
 {
 	if(data==NULL || n<1)
 	{
	 	cout<<"参数有误";
	 	return 0; 
    }
    int currentSum=0,maxSum=0;
    
    for(int i=0;i<n;i++)
    {
    	currentSum+=data[i];
    	if(currentSum<0)
    	{
	    	currentSum=0;
	}else
	{
    		if(maxSum<currentSum)
    		maxSum=currentSum;
    	}
    }
    return maxSum;
 }</span>

16.磁盘里有100T的数据,每一个数据项有一个Key,数据项按key的升序排列,但是key不连续。每个数据项的大小不一样,但是都不超过1M,每一个数据项以特定的标识符结束。现在内存大小为256M,如何找到指定Key的数据项。

解:100T/256M=2^21,即将100T的文件平均分成2^21份,每份大小为256M。然后把每份的第一个关键字和此关键字对应的文件偏移量扫入内存中,这里需要磁盘随机IO 2^21次,通过关键字比较可以定位出关键字在那一块,再通过二分查找查找关键字所在的位置。
注:每条项目包含4个字节的关键字以及6个字节的文件偏移量,即2^21*10<2^25,故内存256M完全可以容得下2^21条项目。
17.小米2014年招聘笔试题

思路:采用层次遍历的思想。

Node *Connect(Node *root)
{
	if(root==NULL)
		return root;
	Node *Queue[100],*p=root,*prev=NULL;
	int front=0,rear=0;
	Queue[++rear]=root;
	int level=rear;    //标记每一层的最后一个节点。
	while(front<rear)
	{
		p=Queue[++front];
		if(prev==NULL)
		{
			prev=p;
		}else
		{
			prev->slib=p;
			prev=p;
		}
		if(p->lchild!=NULL)
			Queue[++rear]=p->lchild;
		if(p->rchild!=NULL)
			Queue[++rear]=p->rchild;
		if(level==front)
		{
			p->slib=NULL;
			prev=NULL;
			level=rear;
		}
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值