1. 程式人生 > >約瑟夫環的問題---最後剩下哪一個

約瑟夫環的問題---最後剩下哪一個

題意描述:1,……,n這n個數字排成一個圓圈,從數字0開始每次從這個圓圈裡面刪除第m個數字。求這個圓圈中最後剩下的一個數字

解題思路一:模擬一個環,然後每次刪除第m個數字

解題思路二:上述思路可行,但明顯時間複雜度O(mn)。因此還是希望找找刪除數字有什麼規律。
        遞迴公式:       0  ,                 n = 1
                   f(n,m)= {
                                    [f(n-1,m)+m] % n ,   n > 1

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class LastNumberInCircle {

	//解題思路一:模擬一個環,然後每次刪除第m個數字,暴力破解
	private static int LastRemaining(int n, int m) {
		if(n < 1 || m < 1)
			return -1;
		
		List<Integer> list = new ArrayList<Integer>();
		for(int i=0; i<n; i++)//list中新增1-n個編號
			list.add(i+1);
		
		int index = -1;//需要淘汰的編號
		while(list.size()>1){//迴圈結束的條件是環內只有1人
			index = (index + m) % list.size();
			System.out.println(list.get(index));
			list.remove(index--);
		}
		
		return list.get(0);
	}
	
	//解題思路二:上述思路可行,但明顯時間複雜度O(mn)。因此還是希望找找刪除數字有什麼規律。
	//遞迴公式:                0  ,               n = 1
        //	         f(n,m)= {
        //	                   [f(n-1,m)+m] % n ,   n > 1
	private static int LastRemaining2(int n, int m){
		if(n < 1 || m < 1)
			return -1;
		
		int last = 0;
		for(int i=2; i<=n; i++)
			last = (last + m) % i;
		
		return last+1;
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()){
			int n = sc.nextInt();
			int m = sc.nextInt();
			System.out.println(LastRemaining(n, m) + "\t" + LastRemaining2(n, m));
		}
	}
}