昨天晚上公司年會,散了之后一個人走在大街上,想到了很多,來南京有9個月了,2012,新的一年又該何去何從呢。有時候理想和生活很難并行,在一個好的公司上班,有個好的領導,是最讓人期望的了,想起了剛來時面試的一道面試題。
    大概講的是一幅撲克牌,四種花色從A、2、到K,每種花色13張,一共52張,一開始每種花色的按順序擺放,然后進行洗牌:分成2半,將一半的第一張放到另一半的第一張下面,第2張放到另一半的第2張下面,直到一半的所有牌都放到另一半的下面,一次洗牌完成,問至少要洗多少次牌才能恢復成原來的順序。
    假設將這52張牌排好序,分別為1到52,則1到13為一個花色,14到26為一個花色,27到39一共花色,40到52為一個花色。假設洗牌之前牌的序號為i,經過一次洗牌過后,1到13序號的牌分到了1到25,則洗牌過后的序號為2i-1;14到26序號的牌被分到27到51,洗牌過后的序號為2(i-13) - 1 + 26;27到39的牌分到了2到26,洗牌過后的序號為2(i - 26) ;40到52序號的牌被分到28到52,洗牌過后的序號為 2(i - 39)  + 26。
    用代碼來表示就是
        public static List<Integer> nextResult(List<Integer> list){
        // return array
        Integer[] retArray = new Integer[52];
        // array index
        int index = 0;
        
        for(int i=1;i<list.size()+1;i++){
            if(i<=13){
                index = 2 * i -1;
            } else if(i >13 && i <= 26){
                index = 2 * (i-13) - 1 + 26;
            }else if(i >26 && i <= 39){
                index = (i - 26) * 2;
            }else if(i >39 && i <= 52){
                index = (i - 39) * 2 + 26;
            }
            
            retArray[index-1] = list.get(i-1);
        }
        
        return Arrays.asList(retArray);
    }
    在main方法里,用下面方式的num便是所要求的最小洗牌次數
        List<Integer> list = new ArrayList<Integer>();
        
        for(int i=1;i<53;i++){
            list.add(i);
        }
        
        // change num
        int num = 0;
        List<Integer> list1 = list;
        while(true){
            num++;
            List<Integer> retList = nextResult(list1);
            if(list.equals(retList)){
                break;
            }
            list1 = retList;
        }