约瑟夫问题Ⅱ:
题目描述
现有n个人围坐一圈,顺时针给大家编号,第一个人编号为1,然后顺时针开始报数。第一轮依次报1,2,1,2…没报1的人出局。接着第二轮再从上一轮最后一个报数的人开始依次报1,2,3,1,2,3…没报1的人都出局。以此类推直到剩下以后一个人。现给定一个int n,要求返回最后一个人的编号。
import java.util.*;
public class Joseph {
public int getResult(int n) {
if (n < 1) return -1;
List<Integer> list = new LinkedList<>();
for (int i = 1; i <= n; i++) {
list.add(i);
}
int bound = 2; //第一次报数的步长
int i, begin = 0; //i为报数人计数器。begin为每人报的数
while (list.size() > 1) { //list剩一个元素退出
i = 0; //开始报数前,i置为0。
while (list.size() > 1 && i < list.size()) { //模拟报数,没报到1的人直接删除
begin = (begin + 1) % bound;
if (begin != 1) {
list.remove(i);
} else {
i++;
}
}
//题目:接着第二轮再从上一轮最后一个报数的人开始依次报
//也就是,上一轮没被删除的最后一个,提到头,继续顺序报数
int last = list.remove(list.size() - 1);
list.add(0, last);
begin = 0; //begin置0重新开始
bound++; //下一轮报数的步长是上一轮+1
}
return list.get(0);
}
}
猫狗收容所:
题目描述
给定一个栈及一个操作序列int[][2] ope(C++中为vector<vector>),代表所进行的入栈出栈操作。第一个元素为1则入栈,第二个元素为数的正负号;第一个元素为2则出栈,第二个元素若为0则出最先入栈的那个数,为1则出最先入栈的正数,为-1则出最先入栈的负数。请按顺序返回出栈的序列,并做异常处理忽略错误操作。
class CatDogAsylum {
public ArrayList<Integer> asylum(int[][] ope) {
ArrayList<Integer> list = new ArrayList<>();
ArrayList<Integer> result = new ArrayList<>();
for(int i = 0;i < ope.length;i++){
if(ope[i][0] == 1){
list.add(ope[i][1]);
}else if(ope[i][0] == 2){
if(ope[i][1] == 0){
result.add(list.remove(0));
}else if(ope[i][1] == 1){
for(int j = 0;j < list.size();j++){
if(list.get(j) > 0 ){
result.add(list.remove(j));
break;
}
}
}else if(ope[i][1] == -1){
for(int j = 0;j < list.size();j++){
if(list.get(j) < 0 ){
result.add(list.remove(j));
break;
}
}
}
}
}
return result;
}
}
栈的弹出压入序列:
题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
class IsPopOrder {
/**
* 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。
* 假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,
* 但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
*/
public boolean IsPopOrder(int [] pushA,int [] popA) {
Stack<Integer> stack = new Stack<>();
int j = 0;
// 模拟实现弹出序列:pushA 压一次判断一次,如果当前栈顶元素等于弹出序列的第一个元素,则把当前元素出栈,同时弹出序列指针后移。
// 也就是说,第一个弹出元素已经得到确定,开始判断后边的序列.否则,继续压入,继续判断直到确定第一个弹出元素
// 如最后栈不为空,则不存在此POP序列
for(int i = 0; i < pushA.length;i++){
stack.push(pushA[i]);
while (!stack.isEmpty() && stack.peek() == popA[j]){
stack.pop();
j++;
}
}
return stack.isEmpty();
}
}