45 扑克牌顺子

题目要求:
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。

分析:

我们只要知道这个数列中最大的数和最小的数,如果不含0,则MAX-MIN=4;如果含10,那么MAX-MIN=4或者3;如果含有20,那么MAX-MIN=4或者3或者2

归纳一下就是,如果5个数(含0)是连续的,那么最大值和最小值的差值必然小于等于4。当然我们还要排除0外其他数字重复出现的情况。

 

所以我们的算法可以如下进行:

 

Step1:保证除0外其他数字不重复出现(代码中用一长度14动态数组,分别记录1-13各数字的出现次数);

 

Step2:计算MAX-MIN的值是否小于4

 1 public class Solution {
 2     public boolean isContinuous(int [] numbers){
 3         //考虑特殊情况,numbers==null 或者 number.length<5,都不如下面的代码来的精辟
 4         if(numbers.length != 5 ) return false;
 5         int max = -1; 
 6         int min = 14;
 7         int[]d = new int[14]; 
 8         d[0] = -5; 
 9         int len = numbers.length; 
10         //整个for循环是为了找出numbers的5个数中,0除外,是否有重复的
11         for(int i =0;i<len;i++){
12             d[numbers[i]]++; 
13             if(numbers[i] == 0) continue; 
14             if(d[numbers[i]]>1) return false; 
15             if(numbers[i] >max) max = numbers[i]; 
16             if(numbers[i] <min) min = numbers[i]; 
17         }
18         if(max-min <= 4){
19             return true; 
20         }
21         return false;
22     }
23 }

 

 

 

 

额外的分析:

这道题的意思很明确,我们玩扑克的过程中,也经常碰到这样的情况。我们先看看在现实生活中,我们是怎么样处理的,我想大部分人都是这样做的:先把5张牌从小到大进行排序,然后直接判断。而如果碰到大小王,我们会除去大小王之后排序,然后判断不相邻的两个数字之间的“距离“,如果该距离<=大小王的数量相等,那么OK,依然是顺子。此外,我们还要考虑,除0外其余数字不能重复出现,对应到现实的扑克牌中即对子不是顺子。为了处理方便,我们把大小王看成00可以替代1-13的任何数字。

有了上面的分析,我们得到常规处理的基本步骤是:

Step1:排序

Step2:计算0的个数

Step3:计算相邻数字的“距离”,并且保证除0外相邻数字不能重复

Step4:比较“距离”是否小于0的个数。

 

本博客也借鉴了一下两个链接的思想,对他们表示感谢

https://blog.csdn.net/ningbo2016/article/details/84024156

https://www.cnblogs.com/w2206/p/7766382.html

posted @ 2019-07-24 10:18  淡如水94  阅读(391)  评论(0)    收藏  举报