扑克牌的顺子问题(Python)
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字。
第一种方法是以大小王做0,计算空缺位置,若不大于0的个数则为匹配。该方法需要首先将牌进行排序。
1 def is_continuous(numbers): 2 """ 判断抽取的5张牌是否是顺子。 3 4 Args: 5 numbers: 抽取的5张牌。 6 7 Returns: 8 布尔变量,表示是否是顺子。 9 """ 10 if len(numbers) < 1: 11 return False 12 numbers.sort() 13 14 num_of_zero = numbers.count(0) # 统计数组中0的个数 15 num_of_gap = 0 16 17 # 统计数组中的间隔数目 18 small = num_of_zero 19 big = small + 1 20 while big < len(numbers): 21 if numbers[small] == numbers[big]: # 有重复元素,不可能是顺子 22 return False 23 num_of_gap += numbers[big] - numbers[small] - 1 24 small += 1 25 big += 1 26 return False if num_of_gap > num_of_zero else True
第二种方法简单粗暴,直接用hash表来做,避免了排序。Python中可以使用dict,其它语言可以建立长度为13的数组做hash。
得到hash表后只需计算最大的键值和最小的键值的差,若小于4,不需考虑有多少大小王,都可以组成顺子。
1 def is_continuous_hash(numbers): 2 """ 判断抽取的5张牌是否是顺子。使用hash方法。 3 4 Args: 5 numbers: 抽取的5张牌。 6 7 Returns: 8 布尔变量,表示是否是顺子。 9 """ 10 if len(numbers) < 1: 11 return False 12 cards = {} 13 for num in numbers: 14 if num == 0: 15 continue 16 if num in cards.keys(): 17 return False 18 else: 19 cards[num] = 1 20 return True if max(cards.keys()) - min(cards.keys()) <= 4 else False
程序代码见:https://github.com/meantobe/blog/blob/master/algorithm/continous_cards.py
参考资料:
1. http://zhedahht.blog.163.com/blog/static/25411174200951262930831