劍指offer——(12)約瑟夫出圈
阿新 • • 發佈:2018-11-30
關於約瑟夫出圈是有一個故事的,去年資料結構課老班有講過,記不清了,有興趣的可以自己去搜下。想起來當年剛學連結串列老師佈置了這麼一道類似的題,我還覺得很難,難到我根本寫不出來,,絞盡腦汁又看了題解才交了作業,現在回過頭去看,其實是很簡單的一道演算法題。
我這裡加了個連結串列版,算是擴充,可以決定第一次的時候從第幾個開始計數,思路全寫在註釋裡了,表達能力欠佳,應該能看懂吧哈哈哈。
public class Solution { public int LastRemaining_Solution(int n, int m) { if(n==0||m==0) return -1; int circle[] = new int[n]; for(int i=0;i<n;i++) circle[i] = i; int i=0,j = 0; while (n > 0) { j = (i + m - 1) % n; i = j; for (; j < n - 1; j++) { circle[j] = circle[j + 1]; } n--; } return circle[j]; } }
import java.util.Scanner; public class Solution { Node head=new Node(); //頭結點 指標 不儲存data Node t=head; public Solution() { Scanner sc=new Scanner(System.in); int n=sc.nextInt(); //圍成圈的人數 int k=sc.nextInt(); //從第幾位開始計數 這裡規定可以從0開始 int m=sc.nextInt(); //決定從1數到m出局 //從0開始 連結串列儲存 for(int i=0;i<n;i++){ t = t.next=new Node(i); } //t指向最後一個節點 最後一個節點指回頭節點的next 形成環連結串列 t.next=head.next; //指向第k位 準備從這裡從1開始計數 for(int i=1;i<=k;i++) t=t.next; //temp指向t.next即未成環時第一位 Node temp=t.next; //q指向出圈結點的前驅結點 Node q=null; //出圈開始 全部人出圈就結束 while(n>=1){ //從第k位開始數 數k-1次 此時temp指向的節點出圈 for(int i=1;i<m;i++){ q=temp; //System.out.print(q.data+" "); temp=temp.next; //System.out.println(temp.data); } //第m個人出圈 System.out.println(temp.data); //用前驅結點q刪除出圈結點 q.next=temp.next; //同時繼續出圈遊戲的temp環連結串列也要指向下一個節點 temp = temp.next; //遊戲人數不斷減少 n--; } } public static void main(String args[]){ new Solution(); } } class Node{ public int data; public Node next; public Node(){ } public Node(int data){ this.data=data; this.next=null; } }