昨天晚上公司年会,散了之后一个人走在大街上,想到了很多,来南京有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;
}