您的位置:首页 > 职场人生

面试题

2013-10-29 13:32 211 查看
1.(百度)一个桶里面有白球、黑球各100个,现在按下述规则取球:的

i 、每次从通里面拿出来两个球;

ii、如果取出的是两个同色的求,就再放入一个黑球;

ii、如果取出的是两个异色的求,就再放入一个白球。

问:最后桶里面只剩下一个黑球的概率是多少?

这个是百度的面试题目,如果写程序会发现,全是黑色的。

这个问题还是要有计算机的2进制思维,把白色的当做1,黑色当做0,1+1=0,就是取两个白色的,放进去一个黑色的。

1+1=0;

1+0=1;

0+0=0;

最终的结果是0,黑色的,一堆0,1相加。

2、(华为)通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串。

压缩规则:

1、仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc"。

2、压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"。

要求实现函数:

void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr);

输入pInputStr: 输入字符串lInputLen: 输入字符串长度

输出 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;

注意:只需要完成该函数功能算法,中间不需要有任何IO的输入输出

示例

输入:“cccddecc” 输出:“3c2de2c”

输入:“adef” 输出:“adef”

输入:“pppppppp” 输出:“8p”

void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr){
	int i=0;
	char C=*pInputStr;
	int number=1;
	for(i=1;i<lInputLen;i++){
		if(C==*(pInputStr+i)){
			number++;
		}
		else{
			if(number!=1){
				char temp[10];
				itoa(number,temp,10);
				strcat(pOutputStr,temp);
				temp[0]=C;
				temp[1]='\0';
				strcat(pOutputStr,temp);
			}
			else{
				char temp[2];
				temp[0]=C;
				temp[1]='\0';
				strcat(pOutputStr,temp);
			}
			C=*(pInputStr+i);
			number=1;
		}
	}
	if(number!=1){
		char temp[10];
		itoa(number,temp,10);
		strcat(pOutputStr,temp);
		temp[0]=C;
		temp[1]='\0';
		strcat(pOutputStr,temp);
		}
	else{
		char temp[2];
		temp[0]=C;
		temp[1]='\0';
		strcat(pOutputStr,temp);
	}

}


为了用strcat而用strcat,写的不好。没有安全检查,assert( (pInputStr != NULL) && (pOutputStr!= NULL) );


3、网新恒天)2014校园招聘笔试编程题

已知memcpy的函数为: void* memcpy(void *dest , const void* src , size_t count)其中dest是目的指针,src是源指针。不调用c++/c的memcpy库函数,请编写memcpy。

这个是参考答案,别人的。

void* memcpy(void *dst, const void *src, size_t count)      
{      
    //安全检查  
    assert( (dst != NULL) && (src != NULL) );      
  
    unsigned char *pdst = (unsigned char *)dst;      
    const unsigned char *psrc = (const unsigned char *)src;      
  
    //防止内存重复  
    assert(!(psrc<=pdst && pdst<psrc+count));      
    assert(!(pdst<=psrc && psrc<pdst+count));      
  
    while(count--)      
    {      
        *pdst = *psrc;      
        pdst++;      
        psrc++;      
    }      
    return dst;      
}

4、迅雷2014校招笔试编程题(转):

已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}。

链表结点的结构类型定义如下:

struct node  
{  
    int elem;  
    node* next;  
};


填空:

void difference(node** LA , node* LB)  
{  
    node *pa , *pb , *pre , *q;  
    pre = NULL;  
                //1  
    while(pa)  
    {  
        pb = LB;  
        while(   )                 //2  
            pb = pb->next;  
        if(    )                   //3  
        {  
            if(!pre)  
                *LA =      ;     //4  
            else  
                 = pa->next;     //5  
            q = pa;  
            pa = pa->next;  
            free(q);  
        }  
        else  
        {  
                   ;             //6  
            pa = pa->next;  
        }  
    }  
}


1、2、3、4、5、6六行代码依次为

pa = *LA;

pb && pa->elem != pb->elem

pb

pa->next

pre->next

pre = pa;

代码中的指针pa用于指向集合A的元素;pb指向集合B的元素;临时指针q指向需要被删除的元素;pre用于实现删除时结点的链接,与pa保持所指结点的前后继关系。

5 人人校招

给定一个有序数组a,长度为len,和一个数X,判断a数组里是否存在两个数的和为X

函数:bool judge(int * a,int len,int X),存在返回true,否则返回false

这个问题其实挺简单的

bool judge(int *a,int len,int X){
	if(a==NULL||len<=0)
		return false;
	int *first=a;
	int *last=a+len-1;
	while(first<last){
		if(*first+*last>X)
			last--;
		else if(*first+*last==X)
			return true;
		else
			first++;
	}
	return false;
}

6 (阿里巴巴 北邮站)设计一个最优算法来查找一n个元素数组中的最大值和最小值。已知一种需要比较2n次的方法,请给一个更优的算法。请特别注意优化时间复杂度的常数。

有序和无序数组的算法问题,经常出现,排序、最大值最小值、中值等。

分析这个题目,其实我觉得有时候对于没有专门ACM训练过的,可能做算法都是靠灵感,如果想到了,则会通过,否则可能就会想到一些笨方法。这个算法主要是能想到两两比较就好。

2n的情况是遍历两次数组,分别求最大和最小值。

如果要比2n小,分析将数组两两一组,分别比较出最大值和最小值(N/2次比较),然后求这一系列最小值的最小值,一系列最大值的最大值(分别为N/2),最终为3N/2次比较。

这里对最大值和最小值进行比较有交换操作,此时程序会做多于运算,可以考虑不交换。设置一个最大值Max和最小值Min,依次和每一组的两个数据做比较,把较大的值给Max,较小的值给Min,遍历一次就能找到数组的最大值和最小值。

分析方法自点击打开链接

7、(阿里巴巴 北邮站)已知三个升序整数数组a[l], b[m]和c
。请在三个数组中各找一个元素,是的组成的三元组距离最小。三元组的距离定义是:假设a[i]、b[j]和c[k]是一个三元组,那么距离为:

Distance = max(|a[ I ] – b[ j ]|, |a[ I ] – c[ k ]|, |b[ j ] – c[ k ]|)

请设计一个求最小三元组距离的最优算法,并分析时间复杂度。

简单一个图可以看出数轴上3个数的两两之间的差的绝对值为多少,可自行证明之。



可以看出Distance其实就是AC之间距离的两倍,所以只需要AC之间的距离最小即可。

所以相应算法为设置最小值min,分别选取abc三个数组的最小值a[0],b[0],c[0]开始以下操作

选取当前a[i]、b[j]和c[k],计算当前三个数的最大值与最小值差值并更新min,选取当前三个数最小值,假设为a[i],然后将a数组向前滑一个数据,i=i+1,继续上步操作,即可得到结果。

算法的复杂度:三个数组的长度和,(l+m+n)

8、(阿里巴巴 北邮站)在黑板上写下50个数字:1至50.在接下来的49轮操作中,每次做如下动作:选取两个黑板上的数字a和b,擦去,在黑板上写|b - a|。请问最后一次动作之后剩下数字可能是什么?为什么?

这个可以先进行举例,50个数,26-1,27-1,...,50-25,然后奇数个25-25,最终得到25

如果是两两相减,则得到1,不再举例了。。。

可以思考一下,这个数一定是小于50的。。。至于为什么可以自己想。

这个数一定是一个奇数:类似于,01之间的异或操作。50个数中,25个偶数,25个奇数。互相相减后得到的是一个必为奇数。

这个数是50之内的任意奇数,没有证明,感谢/article/1385337.html

只有凑的方法

假设取27这个数,来看如何凑出来。将1-50分成两份,1-27,28,29-50。1-27数组中,计算3-2,5-4,。。。,27-26,最终得到14个1,29-50则得到11个1,最终得到,28,25个1,25个1相减最终可以得到一个1,和28相减,则得到27.这个原理是凑,而凑是这个原理,以一个偶数进行分界,对数据进行相减,可以得到奇数个1,与相应偶数进行相减则得到该偶数的前一个的奇数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: