链表类面试题型之一——约瑟夫环

链表类面试题型之一——约瑟夫环

 

在笔试面试中,链表类是经常重点考的题型。本系列是本人为了准备笔试与面试,综合各类书与博客,整理所得。

希望在此过程中,希望可以深刻理解各种题型,督促自己的学习进步,并且分享给大家。如有错误,非常希望得到指点,不甚感激。

 

题目描述:

  有一个数组a[N]顺序存放0~N-1,要求每隔两个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。以8个数(N=7)为例:{0,1,2,3,4,5,6,7},0->1->2(删除)->3->4->5(删除)->6->7->0(删除),如此循环直到最后一个数被删除。

输入描述:

  每组数据为一行一个整数n(小于等于1000),为数组成员数,如果大于1000,则对a[999]进行计算。

输出描述:

  一行输出最后一个被删掉的数的原始下标位置。

本题也是来自于华为的一条上机题, 也是一个很经典的问题:约瑟夫环问题,相比大家都不陌生。对于约瑟夫环问题,解法也是有很多,比如数组,链表,队列或是直接推导出数学公式。本文,采用了比较普遍的循环链表。对于循环链表,此问题也是最为典型的应用。

实现的步骤也是比较清晰:建立链表,按照步数循环删除结点,直到仅剩一个结点时,为要找的结果。需注意的是在建立链表或是插入,删除操作时,均应对第一个结点特别注意。

实现代码如下:

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

int del_n(int n, int interval){
	node *head, *curr, *temp;
	//生成头结点 
	head = (node*)malloc(sizeof(node));
	head->data = 0;
	head->next = NULL;
	curr = head;
	
	//读入n个数 
	for(int i=0; i<n; i++){
		temp = (node*)malloc(sizeof(node));
		head->data++;
		temp->data = i;
		if(curr == head){//第一个结点 
			temp->next = temp; 
		}else{
			temp->next = curr->next;
		}
		curr->next = temp;
		curr = temp;
	}
	//删除结点 
	temp = head->next;
	while(head->data > 1){
		for(int i=0; i<interval; i++){
			curr = temp;
			temp = temp->next;
		}
		
		curr->next = temp->next;
		temp = temp->next;
		head->data--;
		count++;
	}
	
	return temp->data;
}

对于使用队列的方式,实现约瑟夫环问题,将在下文实现。

不足之处,敬请谅解,欢迎交流。

对于题目与解法的来源,本人尽量给出出处,尊重原创,方便大家寻找。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值