笔试题

1.判断两个数组中是否存在相同的数字

给定两个排好序的数组,怎样高效得判断这两个数组中存在相同的数字? 这个问题首先想到的是一个O(nlogn)的算法。就是任意挑选一个数组,遍历这个数组的所有元素,遍历过程中,在另一个数组中对第一个数组中的每个元素进行binary search。用C++实现代码如下:

bool findcommon(int a[],int size1,int b[],int size2)
{
     int i;
     for(i=0;i 
   

后来发现有一个 O(n)算法。因为两个数组都是排好序的。所以只要一次遍历就行了。首先设两个下标,分别初始化为两个数组的起始地址,依次向前推进 。推进的规则是比较两个 数组中的数字,小的那个数组的下标向前推进一步,直到任何一个数组的下标到达数组末尾时,如果这时还没碰到相同的数字,说明数组中没有相同的数字。

bool findcommon2(int a[], int size1, int b[], int size2)
{
     int i=0,j=0;
     while(ib[j])
               j++;
          if(a[i] 
   
 
   

2.找出单向链表的中间结点

这道题和解判断链表是否存在环,我用的是非常类似的方法,只不过结束循环的条件和函数返回值不一样罢了。设置两个指针p1,p2。每次循环p1向前走一步,p2向前走两步。当p2到达链表的末尾时,p1指向的时链表的中间。

link* mid(link* head)
{
	link* p1,*p2;
	p1=p2=head;
	if(head==NULL || head->next==NULL)
		return head;
	do {
		p1=p1->next;
		p2=p2->next->next;
	} while(p2 && p2->next);
	return p1;
}

3.按单词反转字符串

并不是简单的字符串反转,而是按给定字符串里的单词将字符串倒转过来,就是说字符串里面的单词还是保持原来的顺序,这里的每个单词用空格分开。例如: Here is www.zhuxinquan.com 经过反转后变为: www.zhuxinquan.com is Here 如果只是简单的将所有字符串翻转的话,可以遍历字符串,将第一个字符和最后一个交换,第二个和倒数第二个交换,依次循环。其实按照单词反转的话可以在第一遍遍历的基础上,再遍历一遍字符串,对每一个单词再反转一次。这样每个单词又恢复了原来的顺序。

char* reverse_word(const char* str)
{
     int len = strlen(str);
     char* restr = new char[len+1];
     strcpy(restr,str);
     int i,j;
     for(i=0,j=len-1;i 
      

如果考虑空间和时间的优化的话,当然可以将上面代码里两个字符串交换部分改为异或实现。 例如将

 
          char temp=restr[i];
          restr[i]=restr[j];
          restr[j]=temp;

改为

 
          restr[i]^=restr[j];
          restr[j]^=restr[i];
          restr[i]^=restr[j];

你可能感兴趣的:(算法,null,search,p2p,优化,c)