【去哪儿旅行笔试题】德州扑克
题目描述
德州扑克的花型由N张扑克牌组成(N<8),可以组成的牌型按照价值从高到低来区分分别为:
-
皇家同花顺:最高为Ace(一点)的同花顺。 如:A K Q J 10的同花顺
-
同花顺:同一花色,顺序的牌。 如:K Q J 10 9的同花顺
-
四条:有四张同一点数的牌。 如:4 4 4 4 9
-
葫芦:三张同一点数的牌,加一对其他点数的牌。 如:3 3 3 10 10
-
同花:五张同一花色的牌。 如:J 10 8 7 5的全是红桃的牌
-
顺子:五张顺连的牌。 如:5 4 3 2 A的非同花牌(此牌型为最小的顺子)
-
三条:仅有三张同一点数的牌,其余两张点数不同。 如:9 9 9 5 3
-
两对:两张相同点数的牌,加另外两张相同点数的牌。 如:K K 5 5 2
-
一对:仅有两张相同点数的牌。 如:10 10 9 4 2
-
高牌:不符合上面任何一种牌型的牌型,由单牌且不连续不同花的组成,以点数决定大小。 如:A 10 9 5 3的非同花的牌
这十种牌型分别输出:“HuangJiaTongHuaShun”、“TongHuaShun”、“SiTiao”、“HuLu”、“TongHua”、“ShunZi”、“SanTiao”、“LiangDui”、“YiDui”、“GaoPai”。
(扑克牌有4种花色,分别为(S表示黑桃,H表示红心,C表示草花,D表示方片))
本题的输入为任意小于8的N张牌,得到的结果为这些牌中排序最靠前的类型。
Java代码
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
//皇家同花顺
System.out.println(showDown("SA SK SQ SJ S10 H10 C9"));
//同花顺
System.out.println(showDown("S2 S4 S5 S6 S3 H10 C9"));
//四条
System.out.println(showDown("S2 SK H2 C2 S10 D2 C9"));
//葫芦
System.out.println(showDown("S10 SK C10 CK S9 H10 C9"));
//同花
System.out.println(showDown("SA S2 S6 SJ S10 H10 C9"));
//顺子
System.out.println(showDown("S4 H5 C7 D6 S3 H8 C9"));
//三条
System.out.println(showDown("SA HA CA S2 SJ H10 C9"));
//两对
System.out.println(showDown("C4 S4 D10 SJ S10 HJ C9"));
//1对
System.out.println(showDown("C4 S4 DA SQ S10 HJ C9"));
//高牌
System.out.println(showDown("C4 S5 DA SQ S10 HJ C9"));
}
public static String showDown (String inHand) {
// write code here
String[] str = inHand.split(" ");
//统计每个花色的扑克情况
int[] S=new int[15];
int[] H=new int[15];
int[] C=new int[15];
int[] D=new int[15];
//统计每个值的出现次数
int[] nums=new int[15];
for(int i=0;i<str.length;i++){
int num=0;
String tmp=str[i].substring(1);
if(tmp.equals("A")){
num=1;
}else if(tmp.equals("J")){
num=11;
}else if(tmp.equals("Q")){
num=12;
}else if (tmp.equals("K")){
num=13;
}else{
num=Integer.valueOf(tmp);
}
switch (str[i].charAt(0)){
case 'S':{
S[num]++;
if(num==1){
S[14]++;
}
break;
}
case 'H':{
H[num]++;
if(num==1){
H[14]++;
}
break;
}
case 'C':{
C[num]++;
if(num==1){
C[14]++;
}
break;
}
case 'D':{
D[num]++;
if(num==1){
D[14]++;
}
break;
}
}
nums[num]++;
if(num==1){
nums[14]++;
}
}
//皇家同花顺
if((S[1]==1 && S[10]==1 && S[11]==1 && S[12]==1 && S[13]==1 )|| (H[1]==1 && H[10]==1 && H[11]==1 && H[12]==1 && H[13]==1 ) || (C[1]==1 && C[10]==1 && C[11]==1 && C[12]==1 && C[13]==1 ) || (D[1]==1 && D[10]==1 && D[11]==1 && D[12]==1 && D[13]==1 )){
return "HuangJiaTongHuaShun";
}
//同花顺
int time=0;
for(int i=1;i<15;i++){
if(S[i]>0){
time++;
}else{
time=0;
}
if(time>=5){
return "TongHuaShun";
}
}
time=0;
for(int i=1;i<15;i++){
if(H[i]>0){
time++;
}else{
time=0;
}
if(time>=5){
return "TongHuaShun";
}
}
time=0;
for(int i=1;i<15;i++){
if(C[i]>0){
time++;
}else{
time=0;
}
if(time>=5){
return "TongHuaShun";
}
}
time=0;
for(int i=1;i<15;i++){
if(D[i]>0){
time++;
}else{
time=0;
}
if(time>=5){
return "TongHuaShun";
}
}
//四条
for(int i=1;i<14;i++){
if(nums[i]>=4){
return "SiTiao";
}
}
//葫芦
int time_3=0;
int time_2=0;
for(int i=1;i<14;i++){
if(nums[i]>=3){
time_3++;
}else if(nums[i]==2){
time_2++;
}
}
if(time_3>=2 || time_3==1 && time_2>=1){
return "HuLu";
}
//同花
if(Arrays.stream(S).sum()>=5 || Arrays.stream(H).sum()>=5 || Arrays.stream(C).sum()>=5 || Arrays.stream(D).sum()>=5 ){
return "TongHua";
}
//顺子
time=0;
for(int i=1;i<15;i++){
if(nums[i]>0){
time++;
}else{
time=0;
}
if(time>=5){
return "ShunZi";
}
}
//三条
if(time_3==1 && time_2==0){
return "SanTiao";
}
//两对
if(time_3==0 && time_2>=2){
return "LiangDui";
}
//一对
if(time_3==0 && time_2==1){
return "YiDui";
}
return "GaoPai";
}
}
运行结果
复杂度分析
虽然题目看着比较复杂,但是根据题目意思进行模拟还是比较简单的,需要注意switch代码块的每个case里面需要break跳出。
时间复杂度:O(1)
空间复杂度:O(1)