【面試題】面試題合集二

1.【美團】有n個球,兩我的輪流取球,一次能夠取1或2或3個球,取到最後一個球則獲勝,請問如何取才能獲勝?node

分析:數組

①因爲能夠連續取球,因此不管另外一我的如何取球,咱們均可以根據他取的球數控制在4個(如:他1個我3個,他2個我2個,他3個我1個);函數

②當最後一輪剩4個球,並且輪到另外一我的取球,那麼我就一定能夠贏;spa

那麼假設我先取a個球,而後兩人取球回合爲k輪,那麼由上面兩點能夠知道,n=a+4*k且須要注意a>0設計

所以,當球數爲a+4*k時(a≠0),第一個取球的必贏,第一次取的球數使得剩餘球數爲4*k;當球數爲4*k時(a=0),第一個取球的必輸。指針

2.【美團】有n個球,兩我的輪流取球,一次能夠取1或2或4個球,取到最後一個球則判爲輸,請問如何取才能獲勝?code

分析:(題1的變種題)blog

①因爲不能夠連續取球,因此沒法控制每輪取球數目,但有以下關係:排序

當另外一我的取1個球:一輪能夠取出2,3,5個球;遞歸

當另外一我的取2個球:一輪能夠取出3,4,6個球;

當另外一我的取4個球:一輪能夠取出5,6,8個球;

那麼當每輪取球,我能夠把取球數控制在3或6,即3*k(k=1,2);

②最後一輪剩餘4個球時,不管另外一我的如何取,都會贏;

那麼假設我先取a個球,而後兩人取球回合爲k輪(最後一輪剩4個),每輪取球數爲3或6,因此n=a+3*k''+4且須要注意a>0

所以,當球數n:在n-4後爲3的倍數時(a=0),第一個取球的必輸;當n-4不爲3的倍數(即保證a>0),第一個取球的必贏。此結論對於n=1,2,3,4一樣適用。

3.【人人】有兩個空酒瓶,容量分別爲4斤和5斤,有兩個滿酒的酒桶,要求分得兩個酒瓶均有2斤酒,求分法。

分析:經典的BFS題(請查閱分酒)

嘗試分酒完成前一步的酒瓶與酒桶狀態:

4斤酒瓶     5斤酒瓶    酒桶1    酒桶2

2                 5                -3           -4

4                 2                -2           -4

利用這個結果能夠往好的方向猜測,下面給出一種分發

4斤酒瓶 5斤酒瓶 酒桶1 酒桶2
0 0 0 0
4 0 -4 0
0 4 -4 0
4 4 -8 0
3 5 -8 0
3 0 -3 0
0 3 -3 0
4 3 -3 -4
2 5 -3 -4
2 2 0 -4
4.【XX】鏈表反向:將鏈表指針逆序。

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
	int key;
	struct node *next;
}node;

int main(void){
	node *head, *temp, *pre;
	node *p1,*p2,*p3;
	int n, nk;

	scanf("%d", &n);
	for(nk=0,pre=NULL; nk<n; nk++){
		temp = (node*)malloc(sizeof(node));
		scanf("%d", &temp->key);
		temp->next = NULL;
		if(nk==0)
			head = temp;
		if(pre!=NULL)
			pre->next = temp;
		pre = temp;
	}
	for(temp=head; temp!=NULL; temp=temp->next){
		printf("%d ", temp->key);
	}
	printf("\n");

	for(p1=NULL, p2=head, p3=head->next; p3!=NULL; p1=p2, p2=p3, p3=temp){
		temp = p3->next;
		p2->next = p1;
		p3->next = p2;
	}
	head = p2;
	for(temp=head; temp!=NULL; temp=temp->next){
		printf("%d ", temp->key);
	}
	printf("\n");

	system("pause");
	return 0;
}

5.【美團】對一個單向鏈表進行冒泡排序,要求修改鏈表順序而非交換節點數值。

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
	int key;
	struct node *next;
}node;

int main(void){
	node *head, *temp, *pre;
	node *p1,*p2,*p3, *pend, *pnext, *ptemp;
	int n, nk, flag;

	scanf("%d", &n);
	for(nk=0,pre=NULL; nk<n; nk++){
		temp = (node*)malloc(sizeof(node));
		scanf("%d", &temp->key);
		temp->next = NULL;
		if(nk==0)
			head = temp;
		if(pre!=NULL)
			pre->next = temp;
		pre = temp;
	}
	for(temp=head; temp!=NULL; temp=temp->next){
		printf("%d ", temp->key);
	}
	printf("\n");

	for(temp=head; temp!=NULL; temp=temp->next){
		for(p1=NULL, p2=head, p3=head->next, pend=NULL, flag=0; p3!=pend; p1=p2, p2=p3, p3=pnext){
			pnext = p3->next;
			if(p2->key>p3->key){
                                flag = 1;
				if(p1!=NULL)
					p1->next = p3;
				else
					head = p3;
				p2->next = p3->next;
				p3->next = p2;

				if(temp==p2)
					temp = p3;

				//修正p2,p3
				ptemp = p2;
				p2 = p3;
				p3 = ptemp;
			}
		}
		pend = p2;
                if(flag==0)
                    break;
	}
	for(temp=head; temp!=NULL; temp=temp->next){
		printf("%d ", temp->key);
	}
	printf("\n");

	system("pause");
	return 0;
}

6.【360】假設表達式能夠由an*x^n+an-1*x^(n-1)+...+a1*x+a0來表示(ai不全爲0,ai=0或1),在x未知a[n]已知的狀況下,至少須要進行多少次乘法運算才能獲得全部項?(好比x^3+x^2+x至少須要2次乘法,便可獲得x, x^2, x^3)

(待解答)

7.【人人】設計一個函數,判斷系統大小端。

分析:爲了看清系統大小端,那麼只須要查看int型數如何存儲便可。

①大端系統-->高字節存到低地址,低字節存到高地址;小端系統-->低字節存到低地址,高字節存到高地址;

②數組a[n],存儲地址由小到大分別爲&a[0], &a[1], &a[2], ... , &a[n-1];

已知這些條件,利用數組地址分配關係觀察int型或者其餘類型的數據存儲方式,就能夠得出系統大小端問題。

運行下面的程序能夠一目瞭然:

#include <stdio.h>
#include <stdlib.h>

union judge_big_little{
	unsigned int a;
	unsigned char b[4];
};
int main(void){
	union judge_big_little myjudge;
	myjudge.a=0x12345678;
	printf("%p,%p,%p,%p\n", &myjudge.b[0], &myjudge.b[1], &myjudge.b[2], &myjudge.b[3]);
	printf("%x,%x,%x,%x\n", myjudge.b[0], myjudge.b[1], myjudge.b[2], myjudge.b[3]);
	if(myjudge.b[0]==0x12)
		printf("big endian\n");
	else if(myjudge.b[0]==0x78)
		printf("little endian\n");

	system("pause");
	return 0;
}

8.【人人】設計一個函數,判斷所輸入的字符串是否爲ipv4地址,每一個8位地址前加0視爲可行。(如:00212.00012.232.12是正確的ipv4地址)

分析:先總結判斷ipv4地址是否正確的幾個條件,是一道考察邏輯分析能力的題目。

①是否存在有'0'~'9'或'.'意外的字符;

②'.'出現次數是否低於或超過3次;

③每8位是否超過表示範圍(0~255)。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
	char s[100];
	int slen, k;
	int iptemp, fuhao_cnt, error_flag;

	while(1){
		gets(s);
		slen=strlen(s);
		if(slen==0)
			break;
		if(*s=='.'||*(s+slen-1)=='.'){
			printf("O,oh!!!\n");
			continue;
		}
		for(k=0, iptemp=0, fuhao_cnt=0, error_flag=0; k<slen; k++){
			if(*(s+k)!='.'&&(*(s+k)<'0'||*(s+k)>'9')){
				error_flag=1;
				break;
			}
			if(*(s+k)=='.'){
				iptemp=0;
				fuhao_cnt++;
				if(fuhao_cnt>3){
					error_flag=1;
					break;
				}
			}
			else{
				iptemp=iptemp*10+*(s+k)-'0';
				if(iptemp>255){
					error_flag=1;
					break;
				}
			}
		}
		if(fuhao_cnt!=3)
			error_flag=1;
		if(error_flag)
			printf("O,oh!!!\n");
		else
			printf("bingo\n");
	}

	system("pause");
	return 0;
}

9.【人人】求一個數列第n個元素,3*i,5*j,i,j都是從1開始,而後輸出前n個數,若是同時知足能被3和5整除只顯示一遍,例如3,5,6,9,10,12,15,18。

分析:

從0到3,5的最小公倍數15之間有元素3, 5, 6, 9, 10, 12, 15共7個;

從15到3,5的最小公倍數*2=30之間有元素18, 20, 21, 24, 25, 27, 30共7個;

所以,可得規律:當求第n個元素時,可得元素位於15*(n-1)/7與15*((n-1)/7+1)之間,而一個區間內元素偏移量分別爲pianyiliang[7]={3, 5, 6, 9, 10, 12, 15}。

得知以上規律能夠快速得出所求值=15*(n-1)/7+pianyiliang[(n-1)%7]。

如:

所求數爲第7個,則元素爲15*(7-1)/7+pianyiliang[(7-1)%7]=15;

所求數爲低12個,則元素爲15*(12-1)/7+pianyiliang[(12-1)%7]=25。

10.【360】求一棵二叉樹的高度。

分析:只須要將樹遍歷一遍,便可得知樹的高度;使用遞歸能夠輕鬆解決問題。

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
	struct node* lc;
	struct node* rc;
	int id;
}treenode;

//輸入1 2 4 # # 5 8 # # 9 10 # # # 3 6 # 11 # # 7 # #
void preorder_create_tree(treenode **T){
	char ch;
	int fuhao=1, datatemp;

	setbuf(stdin, NULL);
	ch = getchar();
	datatemp = 0;
	while(ch!='\n'&&ch!='#'){
		if(ch=='-')
			fuhao = -1;
		else
			datatemp = datatemp*10+ch-'0';
		//setbuf(stdin, NULL);
		ch = getchar();
	}
	datatemp = fuhao*datatemp;

	if(ch=='#'){
		*T = NULL;
		return;
	}
	else{
		*T = (treenode*)malloc(sizeof(treenode));
		(*T)->id = datatemp;
		preorder_create_tree(&(*T)->lc);
		preorder_create_tree(&(*T)->rc);
	}
}

void pre_visit(treenode *T){  //遞歸法
	if(T!=NULL){
		printf("%d ", T->id);
		pre_visit(T->lc);
		pre_visit(T->rc);
	}
	else{
		return;
	}
}

int count_height(treenode* T){
	static int h_max=0;
	static int h=0;

	if(T==NULL){
		if(h>h_max)
			h_max=h;
		return;
	}
	h++;
	count_height(T->lc);
	count_height(T->rc);
	h--;

	return h_max;
}

int main(void){
	treenode *tree;

	preorder_create_tree(&tree);
	pre_visit(tree); printf("\n");
	printf("height is:%d\n", count_height(tree));

	system("pause");
	return 0;
}
相關文章
相關標籤/搜索