题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
题目注意事项:1)大小王输入为0但是其实可以为任意牌 2)题目中并没有说明有几副牌,所以每个数字的出现都不一定只有两张或者四张。
思路:
读题可得到的条件:
⭐ 根据顺子是5张连续排的这一特点,可知 最大牌-最小牌<5 如 1 2 3 4 5 5-1=4<5 2 0 0 3 5 5-2=3<5
⭐ 且要排除有相同值的情况,如 1 2 2 4 5也满足条件一
做题的方向
确定两个基本要考虑的点之后 最主要求 最大值 最小值 以及 如何排除相同情况
♥ 题目中的例子可能会给人以误导(输入的数组是增序的),但是根据题目要求,我们是随机抽取的,所以输入的数组实际上是乱序的。但是这也可以给我们提供一个思考方向。
即 可以首先对输入的数组进行排序,此时最大值位置就确定了 然后遍历求最小值下标以及让相邻的两个值不相等即可。
♥ 当我们直接使用乱序的数组,可以通过遍历求得最大值和最小值。那么如何保证没有除0外的相同元素呢,可以使用集合。
复杂度: 时间复杂度O(1) 空间复杂度O(1) (两种做法的时空复杂度相同)
PS: ① 初始化一个集合 a = set() 增加元素用 add函数
② 直接调用python中的sort函数用的是快排 时间复杂度为O(nlogn)
直接使用乱序的数组
'''
思路:
例1: 1 2 3 4 5 此时5-1-1=3 代表最大值和最小值中间有三个数 说明5个值肯定是顺序的
例2: 0 1 2 3 5 因为0可以代表任意值 此时我们跳过0来取最小值和最大值 5-1-1=3 仍然代表最大值和最小值中间有三个数 而0可以填补中间的值
例3: 2 4 3 0 5 0可以替代1或6 5-2-1 = 2 也可满足要求
PS1:但是三个例子都有一个问题 最大值最小值肯定是确定的,那么如何保证中间的值是真正递增的呢 例1中间如果不是234,那么应该是223 224等等 就会出现重复数。 例2可能会是0 1 2 2 5
这时候再考虑重复值的问题即可。
PS2:问题2是,虽然示例中的nums是按照增序给的 但是题目中并没有说明 应当按照乱序处理。 如 输入的是 [5 1 2 0 3] [5 3 2 1 4]
复杂度:时间复杂度O(n)=O(5)=O(1) 空间复杂度O(n)=O(5)=O(1)
PS: 初始化一个集合 a = set() 增加元素用 add函数
'''
def isStraight(nums):
minval, maxval, repeat = 14, -1, set()
for item in nums:
if item == 0:
continue
else:
minval = min(minval, item)
maxval = max(maxval, item)
if item not in repeat:
repeat.add(item)
else:
return False
if maxval - minval - 1 <= 3: # 也考虑到了所有元素都为0的情况
return True
else:
return False
对数组进行排序后使用
'''
思路:借助于上边的分析 输入一般是乱序的 如果我们排了序后则最大值位置知道,只要求一个最小值以及保证邻近没有重复值即可。
与思路1对比 相对来说是时间(排序)花费的多一些,而空间(不需要集合了)花费y的少一些。但是由于输入长度已知为5 所以二者的时空复杂度相同都为O(1)
例: 1 2 3 4 5 当没有0时 最大牌-最小牌 = 4
0 0 1 2 5 当有0时,忽略掉。 最大值-最小值 = 4
0 0 1 2 4 当有0时,忽略掉。 最大值-最小值 = 3
当然例1 2有以下反例
0 0 2 2 5 5-2=3<5 但是有两个重复值2,故这时候就要判断相邻的两个值的关系了 如果相等 立刻返回false
复杂度: 时间复杂度O(nlogn) = O(5log5) = O(1) 空间复杂度O(1)
PS: 当输入长度一定时,如本题为5 计算可得复杂度为O(1)
(最开始想到的是解法2 但是因涉及排序 就采用了解法1,但是其实算下来解法2的复杂度也不高)
'''
def isStraight2(nums): # nums = [0,13,13,9,12,10]
nums.sort() # nums = [0,9,10,12,13,13]
minind = 0
for i in range(len(nums) - 1): # minind = 1 正好对应最小值的小标
if nums[i] == 0:
minind += 1
else:
if nums[i] == nums[i + 1]:
return False
if nums[-1] - nums[minind] < len(nums):
return True
else:
return False