判断扑克牌能否组成顺子

从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。


组成顺子有一些条件是必须要满足的, 

1.除了大小王之外, 其他牌不能重复

2.除了大小王之外,  最大值-最小值==4(没有零), 最大值-最小值==3或4(有1个零), 最大值-最小值==2或3或4(有2个零) , 但是看到了别人的优化版, 这几种情况可以统一为 最大值-最小值<5即可, 不需要看0个数量

tip : 使用set可以方便的查看数组中是否有重复, 

第一个算法是分开验证2个条件, 更有助于理解 , 第二个算法优化了判断方法,效率更高

func isStraight(_ nums: [Int]) -> Bool {

    var numberOfKing = 0
    var maxValue = 0
    var minValue = 100
    for num in nums {
        if num == 0 {
            numberOfKing += 1
        }

        if num>maxValue {
            maxValue = num
        }
        if num<minValue && num != 0 {
            minValue = num
        }

    }
    // 最大值-最小值 >= 5 肯定不可以, 比如34568
    if maxValue-minValue >= nums.count {
        return false
    }

    // 把数组转成set,利用set查看是否有重复, 检查除0以外有没有重复
    var result = Set(nums)
    result.remove(0)
    // 小于说明非0数字 有重复
    if result.count < nums.count - numberOfKing {
        return false
    }

    // 到这里, 说明是无重复 && 最大值-最小值<=4, 剩余的可以用0补齐
    return true
}

目前来看最优解是下面这个, 同时把第一步和第二步判断了, 只需要遍历一次即可

// 优化版
func isStraight2(_ nums: [Int]) -> Bool {

    var maxValue = 0
    var minValue = 100
    
    var set = Set<Int>()
    
    for num in nums {
        if num == 0 {
            continue
        }

        if num>maxValue {
            maxValue = num
        }
        if num<minValue  {
            minValue = num
        }
        // 如果有重复, 不可以
        if set.contains(num) {
            return false
        } else {
            set.insert(num)
        }
        
    }
    // 最大值-最小值>=5, 比如12346,肯定是不可以的
    if maxValue-minValue >= nums.count {
        return false
    }
    // 到这里, 说明是无重复, 最大值-最小值<=4
    return true
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值