【9】约瑟夫环问题

简介: 题目:给定n个数编号从1~n形成一个环,每次删除环中的第m个数,求最后一个被删除的数。 方案一:把n个数构造成一个环形链表,每次遍历链表删除一个。

题目:给定n个数编号从1~n形成一个环,每次删除环中的第m个数,求最后一个被删除的数。


方案一:把n个数构造成一个环形链表,每次遍历链表删除一个。总的时间复杂度O(n*m),还需要O(n)的空间

方案二:利用数学递推式。详情请见

  

链表法

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

//链表结点
struct ListNode{
    int value;
    ListNode* nextNode;
};

//建立链表
void BuildList(ListNode **headNode, int *arrNum, int n){
	if(arrNum == NULL || n <= 0){
	    return;
	}
	(*headNode)->value = arrNum[0];
	(*headNode)->nextNode = NULL;
	ListNode *preNode = (*headNode);
	//建立剩下的n-1个点
	for(int i = 1; i < n; i++){
	    ListNode *newNode = new ListNode();
	    newNode->value = arrNum[i];
	    newNode->nextNode = NULL;
	    preNode->nextNode = newNode;
	    preNode = newNode;
	}
	preNode->nextNode = *headNode;
}

//删除n-1个点
int GetLastNum(ListNode *headNode, int n, int m){
	if(headNode == NULL || n <= 0 || m <= 0){
	    throw exception("error");
	}
	int count = n;
	ListNode *pNode = headNode;
	while(count > 1){
	    int pos = 1;
	    while(pos < m-1){
	         ++pos;
		 pNode = pNode->nextNode;
	    }
	    ListNode *tmpNode = pNode->nextNode;
	    pNode->nextNode = tmpNode->nextNode;
	    delete tmpNode;
            tmpNode = NULL;
	    --count;
	    pNode = pNode->nextNode;
	}
	return pNode->value;
}

//遍历链表
void PrintListNode(ListNode *headNode){
	ListNode *pNode = headNode;
	cout<<pNode->value<<endl;
	pNode = pNode->nextNode;
	while(pNode != headNode){
	      cout<<pNode->value<<endl;
	      pNode = pNode->nextNode;
	}
}

int main(){
	//样例
	int arrNum[] = {1,2,3,4,5};
	ListNode *headNode = new ListNode();
	BuildList(&headNode, arrNum, 5);
	cout<<GetLastNum(headNode, 5, 3)<<endl;
	return 0;
}


目录
相关文章
|
9月前
|
存储 算法
|
5月前
约瑟夫环问题的几种解法
约瑟夫环问题的几种解法
74 0
|
6月前
|
算法
约瑟夫环问题(三种方法)
约瑟夫环问题(三种方法)
94 0
|
9月前
|
Java
(五)Java数据结构之循环链表解决约瑟夫(Josephus)环问题
(五)Java数据结构之循环链表解决约瑟夫(Josephus)环问题
65 0
|
10月前
|
算法 索引 Python
细究“约瑟夫环”
细究“约瑟夫环”
77 0
|
11月前
约瑟夫环问题
使用queue<int>q记得加上头文件#include<queue>
55 0
约瑟夫环
题目: 已知n个人(以编号1,2,3--n分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人有出列;以此规律重复下去,知道圆桌周围的人全部出列。输出出列顺序和最后剩下的人。
74 0
|
Java
约瑟夫环问题Java实现
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知 n 个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为 k 的人开始报数,数到 m 的那个人出圈;他的下一个人又从 1 开始报数,数到 m 的那个人又出圈;依此规律重复下去,直到剩余最后一个胜利者。
93 0