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;如果含1个0,那么MAX-MIN=4或者3;如果含有2个0,那么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外其余数字不能重复出现,对应到现实的扑克牌中即对子不是顺子。为了处理方便,我们把大小王看成0,0可以替代1-13的任何数字。
有了上面的分析,我们得到常规处理的基本步骤是:
Step1:排序
Step2:计算0的个数
Step3:计算相邻数字的“距离”,并且保证除0外相邻数字不能重复。
Step4:比较“距离”是否小于0的个数。
本博客也借鉴了一下两个链接的思想,对他们表示感谢
作者:shareidea
出处:https://www.cnblogs.com/shareidea94/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号