环形链表的约瑟夫问题_牛客题霸_牛客网编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。。题目来自【牛客题霸】https://www.nowcoder.com/practice/41c399fdb6004b31a6cbb047c641ed8a著名的Josephus问题
据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39个犹太人Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
然而Josephus和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在
第16个与第31个位置,于是逃过了这场死亡游戏。
思路:
代码:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @param m int整型
* @return int整型
*/
typedef struct ListNode ListNode;
ListNode* buyNode(int x)
{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
newnode->val = x;
newnode->next = NULL;
return newnode;
}
ListNode* CreateCircle(int x)
{
ListNode* head = buyNode(1);
ListNode* tail = head;
for(int i = 2;i <= x;i++)
{
tail->next = buyNode(i);
tail = tail->next;
}
tail->next = head;
return tail;
}
int ysf(int n, int m ) {
// write code here
//创建带环链表
ListNode* newTail = CreateCircle(n);
ListNode* newHead = newTail->next;
int count = 1;
//当链表只有一个节点的时候跳出循环
while(newHead->next != newHead)
{
if(count==m)
{
//销毁newHead节点
newTail->next = newHead->next;
free(newHead);
newHead = newTail->next;
count = 1;
}
else
{
//此时不需要销毁节点
newTail = newHead;
newHead = newTail->next;
count++;
}
}
//释放动态申请的空间
//先把要返回的值保存下来
int ret = newHead ->val;
free(newHead);
newHead = NULL;
//此时剩下一个节点就返回该节点中的值
//return newHead->val;
return ret;
}
提交结果: