题目描述
趣小加非常喜爱玩扑克,现在需要从若干副扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。
2~10为数字本身,A为1,J为11,Q为12,K为13;
而 大、小王为0,可以看成任意牌。
另外,"10,J(11),Q (12),K(13),A(1)"也是顺子。
请你帮助趣小加实现上述功能 )补充说明 数组长度为5 数组的数取值为[0,13].
思路
思路 1
本题有一种情况需要特殊处理:例如 0 10 11 12 1 这个序列,它可以转换为 10 J Q K A,因此这里的 A 实际上是作 14 来用的。
我们还应该知道:J Q K A 2 所有跨越 K 的序列都是非法的;
因此我们确定了要处理的两种情况
(1)对于第一种情况的处理,我们先遍历一趟卡片,统计通用牌(大小王)的数量,然后将 0 从数组中移除后排序,接着继续计算它们之间的 gap 差,最后保证 gap 差 <= 0 的个数就是合法顺子;
(2)如果第一种情况没通过,进入第二种情况的处理,对移除了 0 的数组进行排序,判断最小值是否为 1(按照我们之前的分析,想要凑成 10 J Q K A),那么最小值此时必须为 1,如果是将其转换为 14(还需要进行排序);接着走一遍(1)的处理流程即可。
代码
package main
import (
"fmt"
"sort"
)
func FuncA(cards []int) {
zeros := 0
for i := 0; i < len(cards); i++ {
if cards[i] == 0 {
zeros++
}
}
cardsWithoutZero := make([]int, 0, len(cards)-zeros)
for _, num := range cards {
if num != 0 {
cardsWithoutZero = append(cardsWithoutZero, num)
}
}
sort.Ints(cardsWithoutZero)
// A 作为 1 使用时
gaps := 0
for i := 1; i < len(cardsWithoutZero); i++ {
gap := cardsWithoutZero[i] - cardsWithoutZero[i-1]
if gap > 1 {
gaps += gap - 1
}
}
if gaps <= zeros {
fmt.Println(true)
return
}
gaps = 0
// 10 11 12 13 A 因此考虑到 A 时,顺子最小值此时必须为 A
// 一旦不是 A,比如是 2,那么 J Q K A 2 不是合法的
if cardsWithoutZero[0] != 1 {
fmt.Println(false)
return
}
cardsWithoutZero[0] = 14
sort.Ints(cardsWithoutZero)
for i := 1; i < len(cardsWithoutZero); i++ {
gap := cardsWithoutZero[i] - cardsWithoutZero[i-1]
if gap > 1 {
gaps += gap - 1
}
}
if gaps <= zeros {
fmt.Println(true)
return
}
fmt.Println(false)
}
图示
思路 2
先对数组进行排序,然后使用 joker 记录大小王的个数,最后将最大的牌和非王的最小牌(刚好下标就是 joker)的差值和 4 比较即可。
第二种情况的处理方式和思路 1 是类似的,判断第一个非王最小牌是否为 1,如果不是直接返回 false,如果是的话,则判断 14 和非王最小牌的差值是否小于等于 4。
代码
package main
import "sort"
const (
A = 14
)
func isStraight(nums []int) bool {
sort.Ints(nums)
// 用于记录大小王的数量
joker := 0
// 遍历数组,计算大小王数量,并检查是否有连续的数字
for i := 0; i < len(nums)-1; i++ {
if nums[i] == 0 { // 如果是大小王
joker++ // 计数增加
} else if i != len(nums)-1 && nums[i] == nums[i+1] { // 如果有重复的数字,直接返回false
return false
}
}
// 检查最大值与最小值(除去大小王)之差是否小于等于4,是则可以组成顺子
// joker 值刚好指向第一个非大小王的牌
if nums[len(nums)-1]-nums[joker] <= 4 {
return true
}
if nums[joker] != 1 {
return false
}
if A-nums[joker+1] <= 4 {
return true
}
return false
}