[24年秋招 | Funplus笔试第一题] 扑克牌顺子

RoLingG 算法 2024-09-21

24年秋招趣加笔试第一题 | 扑克牌顺子

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

解法:去重 + 排序 + 遍历

func isStraight(nums []int) bool {
    sort.Ints(nums)
    joker := 0
    for i := 0; i < 4; i++ {
        if nums[i] == 0 {
            joker = i + 1
            if joker > 2 {
                return false
            }
        } else if nums[i] == nums[i+1] {
            return false
        }
    }

    if joker == 0 {
        //特殊例子[10,J,Q,K,A]的判断,也就是[1,10,11,12,13],首尾差为12则可能是特殊例子
        if nums[4]-nums[0] == 12 {
            //进一步判断是否是特殊例子,即1后面一个数有序排列是10
            if nums[1]-nums[0] == 9 {
                //是则返回true,不是则进入非特殊例子正常判断
                return true
            }
        }
        //因为排序过了,没有大小王,直接看首尾值差就知道是否是顺子了
        return nums[4]-nums[0] < 5
    } else {
        //有大小王,则获取大小王的张数作为下标,直指有序排列后的最小值下标(注:大小王各只有一张,别忘了)
        //判断是否是特殊例子,这里不用尾减首是因为有大小王存在
        //后面如果是[...,1,10,...],因为是有序排列过的,满足1后面是10就注定是顺子,可以用大小王补充
        if nums[joker+1]-nums[joker] >= 9 {
            return true
        }
        return nums[4]-nums[joker] < 5
    }
}

测试用例:

func main() {
    // 测试函数
    testCases := [][]int{
        {0, 0, 1, 10, 11},   // 顺子
        {0, 2, 3, 4, 5},     // 顺子
        {0, 10, 11, 12, 13}, // 顺子
        {0, 1, 2, 3, 13},    // 不是顺子
        {0, 0, 0, 0, 5},     // 不是顺子
        {1, 2, 3, 4, 5},     // 顺子
        {10, 11, 12, 13, 1}, // 顺子
    }

    for _, testCase := range testCases {
        fmt.Printf("Is straight: %v? %v\n", testCase, isStraight(testCase))
    }
}
PREV
[Kubernetes] 调度策略及相关内容
NEXT
[24年秋招 | Funplus笔试第二题] 数组内第二大数

评论(0)

发布评论