1、问题描述
魔术师利用一副牌中的13张黑桃牌,预先将他们排好后叠放在一起,牌面朝下。对观众说:“我不看牌,只数数就可以次熬到每张牌是什么,我大声数数,你们听,不信?现场演示。”魔术师将牌堆最上面的哪张排数为1,把他翻过来正好是黑桃A,将黑桃A从牌堆抽出放在桌子上,第二次数1、2,将第一张放在牌堆最下面,第二张翻开,正好是黑桃2,也将它抽出放在桌子上。这样依次进行将13将牌全部翻出,准确无误。问牌最开始的顺序是怎样排的。
2、问题求解
创建带有13个空间点的循环链表,模拟魔术师数数翻牌,第一次翻出的位置是黑桃A,,设置链表改位置节点值为1,第二次翻出的位置是黑桃2,,设置链表改位置节点值为2,依次类推,最终可得牌最开始的排列顺序。
package test.algorithm.FastSlowPointer;public class Magician { public static void main(String[] args){ //创建并初始化有13个节点的链表, 0代表节点值为空 Node header = null; Node pointer = header; for(int i=1;i<=13;i++){ Node temp = new Magician.Node(0); if(header==null){ header = temp; }else{ pointer.next = temp; } pointer = temp; pointer.next = header; } System.out.print("创建13个节点的空链表:"); printList(header); //根据魔术师发牌逆推牌的开始顺序 pointer = header; int countNum = 1 ; while(true){ //按顺序查找揭牌位置 for(int i=1;i13){ break; } } System.out.print("牌的开始顺序:"); printList(header); } static class Node { private int num; private Node next; public Node(int num){ this.num = num; } } /** * 打印链表 * @param node */ static void printList(Node header){ Node pointer = header; do{ System.out.print(pointer.num+" "); pointer = pointer.next; }while(pointer!=null && pointer!=header); System.out.println(); }}