一、題目
從撲克牌中隨機抽5張牌,判斷是不是一個順子, 即這5張牌是不是連續的。2~10為數字本身, A為1。 J為11、Q為12、 為13。小王可以看成任意數字。
二、解題思路
我們可以把5張牌看成由5個數字組成的數組。大、小王是特殊的數字,我們不妨把它們都定義為0,這樣就能和其他撲克牌區分開來了。
接下來我們分析怎樣判斷5個數字是不是連續的,最直觀的方法是把數組排序。值得注意的是,由於0可以當成任意數字,我們可以用0去補滿數組中的空缺。如果排序之后的數組不是連續的,即相鄰的兩個數字相隔若干個數字,但只要我們有足夠的。可以補滿這兩個數字的空缺,這個數組實際上還是連續的。舉個例子,數組排序之后為{0,1,3,4,5}在1和3之間空缺了一個2,剛好我們有一個0,也就是我們可以把它當成2去填補這個空缺。
於是我們需要做3 件事情: 首先把數組排序,再統計數組中0 的個數,最后統計排序之后的數組中相鄰數字之間的空缺總數。如果空缺的總數小於或者等於0 的個數,那么這個數組就是連續的:反之則不連續。
最后,我們還需要注意一點: 如果數組中的非0 數字重復出現,則該數組不是連續的。換成撲克牌的描述方式就是如果一副牌里含有對子,則不可能是順子。
public class Test {
/**
* 題目:從撲克牌中隨機抽5張牌,判斷是不是一個順子, 即這5張牌是不是連續的。
* 2~10為數字本身, A為1。 J為11、Q為12、 為13。小王可以看成任意數字。
* @param numbers
* @return
*/
public static boolean isContinuous(int[] numbers) {
if (numbers == null || numbers.length != 5) {
return false;
}
// 對元素進行排序
Arrays.sort(numbers);
int numberOfZero = 0;
int numberOfGap = 0;
for (int i = 0; i < numbers.length && numbers[i] == 0; i++) {
numberOfZero++;
}
// 一副牌中不可能有兩個以上的王
if(numberOfZero > 2) {
return false;
}
// 第一個非0元素的位置
int small = numberOfZero;
int big = small + 1;
while (big < numbers.length) {
if (numbers[small] == numbers[big]) {
return false;
}
numberOfGap += (numbers[big] - numbers[small] - 1);
small = big;
big++;
}
return numberOfGap <= numberOfZero;
}
}