编号为 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); } }