约瑟夫环1,2

//人编号0...n-1,报号0...m-1,删除第m个即报号m-1的人
	public int joseph(int n,int m){
		if(n==0||m==1) return -1;
		if(n==1) return 0;
		int last=0;
		for(int i=2;i<=n;i++){
			last=(last+m)%n;
		}
		return last;
		
	}
	
	
	/*n个人站一排(1...n),第一轮报号1,2,1,2...删除报号为2的;
	 * 第二轮剩下的人报号1,2,3,1,2,3...删除报号2,3的
	 * 最后剩下一个人,他的编号是多少
	 */
	public int joseph2(int n) {//
		if (n < 1)return -1;
		LinkedList list = new LinkedList();
		int round = 2, i, curr = 0;
		for (i = 1; i <= n; i++) {// 人标号从1到n人
			list.add(i);
		}
		while (list.size() > 1) {//多个人
			i = 0;//i为当前元素在链表中的位置
			while (list.size() > 1 && i < list.size()) {
				curr = (curr + 1) % round;//当前人的序号
				if (curr != 1) {//根据规则:round=2时删除报号为2的,round=3时删除报号为2 3的, 也就说只有当前报号%round==1不被删除
					list.remove(i);//删除了位置i的元素,后面的元素变到位置i的位置
				} else {
					i++;
				}
			}
			round++;// 下一轮的最大报数
			curr = 0;// 表示还未开始报数
			if (list.size() > 1) {// 将最后报数的元素移动到链表首部,即确保每次报数从链表首部开始。
				int last = list.removeLast();	
				list.addFirst(last);
			}
		}
		return list.pop();// 返回最后一个元素
	}

你可能感兴趣的:(剑指offer)