首先,我最大的學習來源不是百度而是我群友~~在這里表白一波我熱愛學習的群友們!
然后今天群里突然有人提出了題目的這個問題:
有n個人圍成一圈,順序排號。從第一個人開始報數(從1到3報數),凡報到3的人退出圈子,問最后留下的是原來第幾號的那位。
冥思苦想了半天(好吧,我承認我就審了審題目就百度了。。),然后查到了幾種算法吧,但是我不知道是因為我只會java還是真的有的人的思路比較廣泛,跳躍,所以看起來略復雜啊。
然后有仔細看了半天,稍微好一點勉強看懂了,但是我覺得還是不簡單,而且是思維上的繞圈。
但是我還把我看過的感覺上挺全的(主要是內容很多)的鏈接在此粘一下,有興趣的同學可以去看看:https://blog.csdn.net/weixin_38214171/article/details/80352921
然后繼續說我又在網上找了找,果然找到一種我覺得很簡單易懂而且很方便的解決方法,然后我又在其基礎上做了解釋說明,下面是解法:
1 package test; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * 約瑟夫環問題的解決 8 * @author sijia 9 * 10 */ 11 public class Demo1 { 12 13 public static void main(String[] args) { 14 List<Integer> list = new ArrayList<Integer>(); 15 list.add(0); 16 list.add(1); 17 list.add(2); 18 list.add(3); 19 list.add(4); 20 list.add(5); 21 list.add(6); 22 list.add(7); 23 list.add(8); 24 list.add(9); 25 list.add(10); 26 list.add(11); 27 list.add(12); 28 list.add(13); 29 list.add(14); 30 list.add(15); 31 list.add(16); 32 33 34 //思路是遍歷數組,隔兩個刪除一個元素,直到只剩下一個元素。如果到了數組末尾則跳轉開頭 35 int i=0; 36 while(list.size()!=1) { 37 //遍歷到了最后一個元素,i+2是跳轉到正數第二個元素 38 if(i>=list.size()-1) { 39 i=-1; 40 } 41 //遍歷到了倒數第二個元素,i+2是跳轉到第一個元素 42 if(i>=list.size()-2) { 43 i=-2; 44 } 45 //以上完成了數組據末尾跳轉到數組開頭 46 47 i=i+2; 48 /** 49 * 刪除元素 50 * 這里不理解的可以做個帶入。第一次刪除0+2,也就是把下標為2的元素刪除了。第二次繼續,走到這里 51 * i=2+2變成了4.為什么這次刪除下標為4的?因為之前把下標為2的刪除后,后面的元素依次前移了。 52 * 原下標3的現在下標為2.同理,原下標為5的現在下標為4. 53 * 如此:3,4,后面原下標5現下標4的元素刪除。符合了題目的邏輯。 54 * i每次都加2,是因為上一輪刪除了一個元素,整個下標都前移了。所以才會+2代表隔了兩個刪除一個 55 * 同樣大家可以考慮一下這道題的變換:比如題目變成隔5個刪除一個,也就是報數1-6,數到6的出局要怎么寫? 56 * 57 */ 58 list.remove(i); 59 60 } 61 /** 62 * 最后打印出來的就是剩下的那個元素,因為我這里取巧,將下標和元素的值對應了,所以我們不僅可以看出元素的值 63 * 還可以看元素原來的下標。如果不這么做可以在一開始就復制一份list,然后用最后剩下來的值去反推,再不濟還能不移除而是用別的方法標記出局。這樣要改動的比較大 64 * 這個 數值與數組list的總元素數,也就是題目中的N息息相關,我反正試了多次。 65 */ 66 System.out.print(list.get(0)); 67 68 } 69 70 }
至此,問題解決,然后文中我留了兩個問題:
1.這個人數n和排除的數m之間是有一定關聯關系的,但是我這個數學渣有點沒耐心一遍遍測試或者思考了,所以作為一個遺留問題吧。
2.我文中說的,這個方法是實現N個人數到3退出的代碼。但是如果題目是N個人數到5退出呢?又該怎么寫?反正我目前是有思路了,有意的可以私信我探討哦~~
全文手打不易,如果稍微幫到你了,請點個喜歡點個關注支持一下~~~~~也祝大家工作順順利利!
