链表类面试题型之一——约瑟夫环
链表类面试题型之一——约瑟夫环
在笔试面试中,链表类是经常重点考的题型。本系列是本人为了准备笔试与面试,综合各类书与博客,整理所得。
希望在此过程中,希望可以深刻理解各种题型,督促自己的学习进步,并且分享给大家。如有错误,非常希望得到指点,不甚感激。
题目描述:
有一个数组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; }
对于使用队列的方式,实现约瑟夫环问题,将在下文实现。
不足之处,敬请谅解,欢迎交流。
对于题目与解法的来源,本人尽量给出出处,尊重原创,方便大家寻找。

浙公网安备 33010602011771号