1.升序排列下列数值:(101001)2,(40)10,(23)8,(18)16
解:个人理解,全统一到某一进制,如10进制数,再进行比较。
2.写出下列函数的返回值int func(int x=300){ int y=0; while(x){ y++; x=x&(x-1); } return y; }
解:x = x&(x-1)的作用是将x(二进制表示)最右边的1消去,所以,程序的功能是求x的二进制表示法有多少个1.因为300(10)=100101100(2),所以返回值是4.
3.写出下面代码的输出#include<stdio.h> int main(){ char *p="abcdef"; char str[]="123456"; printf("d%\n",*(p+4)); printf("c%\n",p[4]); printf("c%\n",*(str+4)); printf("c%\n",str[4]); return 0; }
解:这道题出得十分YD,注意是d%而不是%d,所以,你懂的。答案是,一不小心,可能会跌爆眼镜!
d
c
c
c
4.使用C语言写出存储内容为整数的单链表数据类型定义,并使用自己定义的单链表数据类型定义,完成下面的算法,要求优化时间与空间复杂度。输出:1->2->3->4->5
解:合并两个链表的方法其它同类型的面试题已经有讲过不少了,这里多了一个“去重”要求。只需要多处理一种情况即可。下面用的是C++,稍作改进就可以变成C.
#include<iostream> using namespace std; struct node { int key; node* next; node(int k):key(k),next(NULL){} }; struct List { node* head; List():head(NULL){} }; node* ListInsert(node* head,node* z) { if(!head) { head=z; return head; } else { head->next=ListInsert(head->next,z); return head; } } node* recurMergeList(node* head1,node* head2) { if(!head1)//如果没有head1 return head2; else if(!head2)//如果没有head2 return head1; node* MergeHead=NULL; if(head1->key < head2->key) { MergeHead=head1; MergeHead->next=recurMergeList(head1->next,head2); } else if(head1->key > head2->key ) { MergeHead=head2; MergeHead->next=recurMergeList(head2->next,head1); } else //head1->key ==head2->key { //新增的部分 MergeHead=head1 ; node* nextMergeHead = recurMergeList(head1->next,head2->next); if(nextMergeHead && MergeHead->key == nextMergeHead->key) MergeHead=nextMergeHead; else MergeHead->next = nextMergeHead; } return MergeHead; } void main() { int A[]={1,2,2,5,9,13,16}; int B[]={2,5,12,13,13,16,19}; int len=sizeof(A)/sizeof(A[0]); List* LA=new List; for(int i=0;i<len;++i) { LA->head=ListInsert(LA->head,new node(A[i])); } List* LB=new List; for(int i=0;i<len;++i) { LB->head=ListInsert(LB->head,new node(B[i])); } node* p=LA->head; while(p) { cout<<p->key<<' '; p=p->next; } cout<<endl; p=LB->head; while(p) { cout<<p->key<<' '; p=p->next; } cout<<endl; p=recurMergeList(LA->head,LB->head); //p=MergeList(LA->head,LB->head); while(p) { cout<<p->key<<' '; p=p->next; } }5.编写程序,把一个有序整数数组放到以整数为元素的二叉树中,生成一个平衡排序二叉树。设计并变成实现一种遍历方法,,是这种遍历方法的输出正好是输入数据的次序。
1 3 5 7
解:本来将一个有序数组放到一棵二叉树有很多种摆放方式,但是题目要求是平衡二叉树,容易想到的是二分思想,当每个结点左边和右边的结点数相等(或只相差1个的时候)这棵树就是平衡的,最后再中序输出即可。
#include<iostream> #include <exception> using std::cout; using std::endl; struct node { int value; node* left; node* right; node(int v):value(v),left(NULL),right(NULL){} }; node* Build_Tree(int* A,int l,int r) { if(!A || l > r) return NULL; int mid = (l+r)>>1; node* root = new node(A[mid]); root->left = Build_Tree( A, l, mid-1); root->right = Build_Tree( A, mid+1,r); return root; } void TreeWalk(node* z) { if(!z) return ; TreeWalk(z->left); cout<<z->value<<' '; TreeWalk(z->right); } int main() { int Inorder[] = {1,2,3,4,5,6,7}; int len=sizeof(Inorder)/sizeof(Inorder[0]); node* root=Build_Tree(Inorder,0,len-1); TreeWalk(root); return 0; }6.编写程序,在原字符串中把尾部m个字符移动到字符串的头部,要求:长度为n字符串操作时间复杂度为O(n),空间复杂度为O(1)。
如:原字符串为”Ilovebaofeng”,m=7,输出结果:”baofengIlove”
解:具体见http://blog.csdn.net/linraise/article/details/12237185的左旋转部分,5种办法中只有2处是符合要求的。递归要用到栈,空间不是O(1).
7.暴风影音的片源服务器上保存着两个文件a和b,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让你找出a,b文件共同的URL。要求:算法设计。
解:大数据问题。5*64=320G,4G内存无法一次性装入。因此可以用一个hash函数将a文件的URL hash到n个小文件中,对b文件的URL做同样的操作,因此,所有可能相同的URL都会被分到相同的小文件中。因为hash函数的特点是如果a=b,则hash(a)=hash(b).再对每一个小文件统计相同的URL即可,可以两次扫描,也可以用位图。