笔试题

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

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

bool findcommon(int a[],int size1,int b[],int size2)
{
     int i;
     for(i=0;i<size1;i++)
     {
          int start=0,end=size2-1,mid;
          while(start<=end)
          {
               mid=(start+end)/2;
               if(a[i]==b[mid])
                    return true;
               else if (a[i]<b[mid])
                    end=mid-1;
               else
                    start=mid+1;
          }
     }
     return false;
}

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

bool findcommon2(int a[], int size1, int b[], int size2)
{
     int i=0,j=0;
     while(i<size1 && j<size2)
     {
          if(a[i]==b[j])
               return true;
          if(a[i]>b[j])
               j++;
          if(a[i]<b[j])
               i++;
     }
     return false;
}

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<j;i++,j--)
     {
          char temp=restr[i];
          restr[i]=restr[j];
          restr[j]=temp;
     }
     int k=0;
     while(k<len)
     {
          i=j=k;
          while(restr[j]!=' ' && restr[j]!='/0' )
               j++;
          k=j+1;
          j--;
          for(;i<j;i++,j--)
          {
               char temp=restr[i];
               restr[i]=restr[j];
               restr[j]=temp;
          }
     }
     return restr;
}

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

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

改为

 
          restr[i]^=restr[j];
          restr[j]^=restr[i];
          restr[i]^=restr[j];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值