约瑟夫环进阶:
2020个数 围成一个圈,从第一个开始,每过三个,删除三个,例:从1开始,删除2,3,4。求出最后剩下的数是多少?
代码如下:
public static void main(String[] args) {
boolean[] arr= showJoseph(2020,4);
for(int i=0;i<arr.length;i++){
if(arr[i] == true){
System.out.println(i+1);
}
}
}
/**
* 算法题:2020个数 围成一个圈,从第一个开始,每过三个,删除三个,例:从1开始,
* 删除2,3,4。求出最后剩下的数是多少
* 类似约瑟夫环
* @param total
* @param cycle
* @return
*/
private static boolean[] showJoseph(int total, int cycle) {
boolean[] arr = new boolean[total];
Arrays.fill(arr, true);
int kill = 0;
int index = 0;
while (kill < total) {
for (int i = 0; i < cycle; i++) {
List<Integer> indexList = new ArrayList<>();
while (!arr[index]) {
index = (index + 1) % total;
}
if (i == cycle - 1) {
// 将数组中值为true的下标,存入一个新的list中
for(int k = 0; k < arr.length; k++){
if(arr[k]){
indexList.add(k);
}
}
// 如果indexList只有一个值,则为最后解,直接返回。
if(indexList.size() == 1){
return arr;
}
for(int j = 0; j< indexList.size();j++){
// 判断删除点的下标是否
if(index == indexList.get(j)){
arr[indexList.get(j)] = false;
if(j ==0){
// 如果是头结点 就从最后一个开始删
j = indexList.size();
}
arr[indexList.get(j-1)] = false;
arr[indexList.get(j-2)] = false;
break;
}
}
kill++;
// 每次循环 清空indexList
indexList.clear();
}
// 以下代码为重点,没看懂。。。。
// if(kill==total-1) result = (index+1);
index = (index+1) % total;
}
}
return null;
}
如有不对的地方,欢迎评论修改
今天的日期是2021-06-30 14:51,今天在工作学习的时候,突然想起这个问题,于是翻阅自己的博客,看了下之前的解法,发现好蠢,于是自己重新写了一编,主要思路就是用链表的方式,这个方法比之前的写法,代码简单多了。代码如下:
public void test1(){ Node head = new Node(1); Node next = null; for (int i = 2; i <= 2020; i++) { Node node = new Node(i); if (i == 2) { head.next = node; } else if (i == 2020){ // 首尾相连,组成循环链表 next.next = node; node.next = head; }else { next.next = node; } next = node; } int count = 0; // 结束条件就是head.next = head,说明只有一个值了 while(head.next.val != head.val){ if (count == 3) { // 循环四次 删除中间的三个节点 head.next = head.next.next.next.next; // 重新赋值head head = head.next; // count归0 count = 0; } count++; } // 打印结果 System.out.println(head.val); }
以前 这道题 想了好久 还是在网上找的别人的答案,经过不断学习,今天花5分钟就解答出来了,感觉自己进步挺大,感触也挺深。。加油!奥里给!