编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。
下一个人继续从 1 开始报数。
n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是多少?
数据范围:
进阶:空间复杂度
,时间复杂度
5,2
3
开始5个人 1,2,3,4,5 ,从1开始报数,1->1,2->2编号为2的人离开 1,3,4,5,从3开始报数,3->1,4->2编号为4的人离开 1,3,5,从5开始报数,5->1,1->2编号为1的人离开 3,5,从3开始报数,3->1,5->2编号为5的人离开 最后留下人的编号是3
1,1
1
public int ysf (int n, int m) {
// write code here
ListNode p1=new ListNode(1) ,p2=p1;
for(int i=2;i<=n;i++){
p2.next=new ListNode(i);
p2=p2.next;
}
p2.next=p1;
while(p2.next!=p2){
for(int i=1;i<m;i++){
p2=p2.next;
}
p2.next=p2.next.next;
}
return p2.val;
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @param m int整型
* @return int整型
*/
class AAAA {
int i;
int index;
AAAA next;
AAAA pri;
public AAAA(int i, int index) {
this.i = i;
this.index = index;
}
};
public int ysf (int n, int m) {
// write code here
AAAA head = new AAAA(1, 1);
AAAA quene = head;
for (int i = 2; i <= n; i++) {
AAAA p = new AAAA(i % m, i);
quene.next = p;
p.pri = quene;
quene = p;
System.out.println("i:" + i + " " + quene.index + " " + quene.i);
}
quene.next = head;
head.pri = quene;
quene = head;
while (true) {
if (quene.i == m) {
quene.pri.next = quene.next;
quene.next.pri = quene.pri;
quene = quene.next;
quene.i = 1;
} else {
quene = quene.next;
quene.i = quene.pri.i + 1;
}
if (quene.next.index == quene.index) {
break;
}
}
return quene.index;
}
} import java.util.*;
public class Solution {
/**
*
* @param n int整型
* @param m int整型
* @return int整型
*/
public int ysf (int n, int m) {
// write code here
//队列来模拟环
Queue<Integer> queue=new LinkedList<>();
//入队
for(int i=1;i<=n;i++){
queue.add(i);
}
//标记,用来出队
int flag=1;
while(queue.size()>1){
//报号到m则出队
if(flag==m){
queue.poll();
flag=0;
//否则添加到队尾模拟环
}else{
queue.add(queue.poll());
}
flag++;
}
//最后一个人出队
return queue.poll();
}
} public int ysf (int n, int m) {
// write code here
// 1. 永远考虑第一个数的人为1号位
// 2. 考虑f(n, m)和f(n-1, m)的转换关系
// 3. 假设第
int ans = 0;
for(int i = 2; i <= n; ++i) {
ans = (ans + m) % i;
}
return ans + 1;
} stack over
import java.util.*;
public class Solution {
/**
*
* @param n int整型
* @param m int整型
* @return int整型
*/
public int ysf (int n, int m) {
return lastRemaining(n,m)+1;
}
public int lastRemaining(int n, int m) {
if(n==1) return 0;
int x=lastRemaining(n-1,m);//0->x 移动了x个
int val=m%n;
return (x+val)%n;
}
}
public class Solution {
/**
*
* @param n int整型
* @param m int整型
* @return int整型
*/
public int ysf (int n, int m) {
// write code here
// write code here
LinkedList<Integer> list = new LinkedList<>();
for(int i=1;i<=n;i++){
list.add(i);
}
Integer i=0,j= 0;
while(!list.isEmpty()){
i = list.removeFirst();
j++;
if(j%m==0){
j=0;
}else{
list.addLast(i);
}
}
return i;
}
} import java.util.*;
public class Solution {
/**
*
* @param n int整型
* @param m int整型
* @return int整型
*/
public int ysf (int n, int m) {
// write code here
if(n == 1 && m == 1){
return 1;
}
LinkedList<Integer> list = new LinkedList<>();
for( int i = 1; i <= n; i++){
list.add(i);
}
int start = 0;
int del = 0;
while(list.size() != 1){
// 找到要移除的位置
del = (start + m -1) % list.size();
start = del; //新的报数起点
list.remove(del);
}
return list.get(0);
}
} import java.util.*;
public class Solution {
/**
*
* @param n int整型
* @param m int整型
* @return int整型
*/
public int ysf (int n, int m) {
// 循环链表
if (n == 0) return 0;
// 虚拟头节点
ListNode head = new ListNode(-1);
ListNode pre = head;
for (int i = 1; i <= n; ++ i){
pre.next = new ListNode(i);
pre = pre.next;
}
pre.next = head.next;
int count = 0;
pre = head;
ListNode cur = pre.next;
while (cur != cur.next){
++ count;
if (count == m){
pre.next = cur.next;
count = 0;
} else {
pre = pre.next;
}
cur = pre.next;
}
return cur.val;
}
} import java.util.*;
public class Solution {
/**
*
* @param n int整型
* @param m int整型
* @return int整型
*/
public int ysf (int n, int m) {
// write code here
List<Integer> list = new ArrayList<>();
for (int i = 0; i <= n; i++) {
list.add(i);
}
int i = 0;
while (list.size() > 2){
i = (i + m) % (list.size()-1) == 0 ? (list.size() -1) : (i + m) % (list.size()-1);
list.remove(i--);
if(i == 0) i = list.size()-1;
}
return list.get(1);
}
} public class Solution {
public int ysf (int n, int m) {
return joseph(n, m) + 1; // 结果加1,因为人的编号从 1 到 n。Caution!!!
}
// 套用人的编号从 0 到 (n - 1) 的代码
public int joseph(int n, int m) {
if (n == 1) return 0;
return (joseph(n - 1, m) + m) % n;
}
} public class Solution {
// 链表的节点
private static class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
public int ysf (int n, int m) {
// 建立环形链表
ListNode front = new ListNode(-1); // 头节点
ListNode rear = front; // 尾指针
for (int i = 1; i <= n; i++) {
ListNode node = new ListNode(i);
rear.next = node;
rear = node; // 尾插法建立链表
}
rear.next = front.next; // 建立环形链表
int size = n; // 环形链表节点的个数
ListNode prev = front;
ListNode curr = front.next;
while (size != 1) {
for (int i = 0; i < m - 1; i++) {
prev = prev.next;
curr = curr.next; // 走 (m - 1) 步
}
ListNode nextNode = curr.next;
prev.next = nextNode; // 删除curr指向的节点
curr = nextNode; // 更新curr
size--;
}
return curr.val; // 此时prev和curr都指向最后一个节点,所以返回prev.val也可以
}
} import java.util.*;
public class Solution {
/**
*
* @param n int整型
* @param m int整型
* @return int整型
*/
public int ysf (int n, int m) {
ListNode head = new ListNode(1);
ListNode p = head;
//创建一个循环链表
for(int i = 2; i <= n; i++){
ListNode node = new ListNode(i);
p.next = node;
node.next = head;
p = node;
}
ListNode pre = new ListNode(-1);
pre.next = head;
p = head;
int k = 0;
//按间隔删除节点
while(k < n-1){
for(int i = 1; i< m; i++){
pre = pre.next;
p = pre.next;
}
pre.next = p.next;
p.next = null;
k ++;
}
return pre.val;
}
}
class ListNode{
int val;
ListNode next;
public ListNode(){}
public ListNode(int val){
this.val = val;
}
} import java.util.*;
public class Solution {
public int ysf (int n, int m) {
// 一个人或者m为1时
if(n < 2 && m == 1){
return n;
}
// 组成环型链表
ListNode head = new ListNode(1);
ListNode tail = head;
for(int i=2; i<=n; i++){
tail.next = new ListNode(i);
tail = tail.next;
}
tail.next = head;
int count = 0;
while(tail != tail.next){
// 报数
count++;
// 幸运儿
if(count == m){
count = 0;
// 记录位置
head = tail;
// 删除目标结点
tail.next = tail.next.next;
// 返回位置
tail = head;
continue;
}
tail = tail.next;
}
return tail.val;
}
} import java.util.*;
// 暴力法
public class Solution {
public int ysf (int n, int m) {
List<Integer> list = new ArrayList<>();
for(int i=0; i<n; i++)
list.add(i+1);
int lastCurr = 0;
while(list.size()>1) {
n = list.size();
list.remove((lastCurr+m-1)%n);
lastCurr = (lastCurr+m-1)%n;
}
return list.get(0);
}
}