leetcode刷题日记-846. 一手顺子

  • 题目描述:
    Alice 手中有一把牌,她想要重新排列这些牌,分成若干组,使每一组的牌数都是 groupSize ,并且由 groupSize 张连续的牌组成。
    给你一个整数数组 hand 其中 hand[i] 是写在第 i 张牌,和一个整数 groupSize 。如果她可能重新排列这些牌,返回 true ;否则,返回 false 。

  • 示例:
    输入:hand = [1,2,3,6,2,3,4,7,8], groupSize = 3
    输出:true
    解释:Alice 手中的牌可以被重新排列为 [1,2,3],[2,3,4],[6,7,8]。

    输入:hand = [1,2,3,4,5], groupSize = 4
    输出:false
    解释:Alice 手中的牌无法被重新排列成几个大小为 4 的组。

  • 提示:
    1 <= hand.length <= 104
    0 <= hand[i] <= 109
    1 <= groupSize <= hand.length

  • 解析:这道题目的难点在于如何想到考点,我们观察给定的hand,发现他是一个无序数组,本题明显对数组元素顺序有很严格的要求,所以我们首先就可以考虑对数组进行排序。然后再考虑不可能匹配成功的情况,第一种是hand的元素个数对 groupSize取余不等于0,这种很好理解,比如10个元素分成3组,无论如何也不可能做到每组元素一样;第二种是每个group不是连续的牌,这个乍一想有点麻烦,我们可以这么考虑,给了我们一个hand,元素个数为n,我们为他准备n/groupSize个箱子,首先将hand排序,然后取里面最小的元素x1作为第一个箱子的起始元素,而后对k属于[x1, x1+groupSize)每个元素进行两个操作,第一个判断k是否在hand中,如果不在,返回False,如果在,则从hand中取出,遍历完成后,说明第一个箱子满足条件,进行第二个箱子的装填,以目前hand数组的最小元素作为第二个箱子的起始元素,重复上述步骤,当遍历完成后,如果hand里面元素为空,返回True。

  • 当然,我们实际操作时,不能直接对hand进行元素的删减,对应元素的查找和删除会有较高的复杂度,只要涉及到查找,我们第一反应是二分,第二嘛,就是哈希,这题就是用哈希,那么怎么用呢?我们可以记录hand中每个元素对应的个数(一个字典类型的遍历,记为cnt),然后遍历hand,,对每一个元素h,判断cnt[h]是不是等于0,如果不等于0,则以其作为七点,对k属于[h, h+groupSize)进行遍历,如果k不在cnt中,返回False,如果在,但是cnt[k]=0,返回False。遍历完成后如果cnt.values()的和为0,则返回True。但是实际上这一步,可以避免,我们创建一个变量等于hand的元素个数,记为ans,每往箱子里放一个元素,ans减去1,如果遍历完成后,ans=0,返回True,否则,返回False。解题代码如下所示:

class Solution:
    def isNStraightHand(self, hand: List[int], groupSize: int) -> bool:
        """
        给你一个整数数组 hand 其中 hand[i] 是写在第 i 张牌,和一个整数 groupSize 。如果她
        可能重新排列这些牌,返回 true ;否则,返回 false
        >>>self.isNStraightHand([1,2,3,6,2,3,4,7,8], 3)
        >>>True
        >>>self.isNStraightHand([1,2,3,4,5], 4)
        >>>False
        """
        ans = len(hand)
        if ans % groupSize != 0:
            return False
        hand.sort()
        cnt = Counter(hand)
        for h in hand:
            if cnt[h] == 0:
                continue
            else:
                for i in range(groupSize):
                    if h+i not in cnt or cnt[h+i] == 0:
                        return False
                    cnt[h+i] -= 1     
                    ans -= 1   
        return True if ans == 0 else False
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lemon_tttea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值