从扑克牌中随机抽取5张牌,判断这5张牌是否是顺子(即连续)。其中:
核心思想:
1. 排序数组:便于分析连续性
2. 统计大小王数量:可以作为万能牌填补空缺
3. 计算间隔总数:统计非0数字之间的间隔数
4. 检查重复:除0外,其他数字不可重复
关键条件:
python
def is_straight(cards):
判断五张扑克牌是否为顺子
Args:
cards: 包含5个整数的列表,0表示大小王
Returns:
bool: 是否为顺子
if len(cards) != 5:
return False
# 排序
cards.sort
# 统计大小王数量
zero_count = cards.count(0)
# 检查是否有重复的非0牌
for i in range(zero_count, 4):
if cards[i] == cards[i + 1]:
return False
# 计算间隔总数
gap = 0
for i in range(zero_count, 4):
gap += cards[i + 1]
return gap
# 测试用例
def test_is_straight:
test_cases = [
[1, 2, 3, 4, 5], # True: 正常顺子
[0, 0, 1, 2, 3], # True: 双王补位
[0, 0, 0, 0, 1], # True: 四王补位
[1, 3, 4, 5, 6], # False: 缺2
[0, 0, 2, 3, 6], # False: 缺4,5,王不够
[1, 2, 3, 4, 4], # False: 有重复
[11, 12, 13, 0, 0] # True: J,Q,K + 双王
for i, cards in enumerate(test_cases):
result = is_straight(cards)
print(f"测试用例 {i+1}: {cards} -> {'是顺子' if result else '不是顺子'}")
test_is_straight
cpp
#include
#include
#include
using namespace std;
bool isStraight(vector& cards) {
if (cards.size != 5) return false;
// 排序
sort(cards.begin, cards.end);
// 统计大小王数量
int zeroCount = 0;
for for (int card : cards) {
if (card == 0) zeroCount++;
// 检查重复并计算间隔
int gap = 0;
for (int i = zeroCount; i
if (cards[i] == cards[i + 1]) return false;
gap += cards[i + 1]
return gap
// 测试函数
void testIsStraight {
vector> testCases = {
{1, 2, 3, 4, 5},
{0, 0, 1, 2, 3},
{0, 0, 0, 0, 1},
{1, 3, 4, 5, 6},
{0, 0, 2, 3, 6},
{1, 2, 3, 4, 4},
{11, 12, 13, 0, 0}
};
for (int i = 0; i
bool result = isStraight(testCases[i]);
cout
for (int card : testCases[i]) cout
cout "
int main {
testIsStraight;
return 0;
给定一副牌(可能包含大小王),如何摆放才能形成最多的顺子?每个顺子至少包含3张牌。
贪心策略:
1. 统计频率:记录每个数字出现的次数
2. 优先组成小顺子:从最小数字开始尝试组成顺子
3. 动态调整:根据剩余的王牌数量决定顺子长度
python
def max_straights(cards):
计算最多能组成的顺子数量
Args:
cards: 扑克牌列表,0表示大小王
Returns:
int: 最多顺子数量
from collections import Counter
# 统计非王牌频率
freq = Counter([card for card in cards if card != 0])
jokers = cards.count(0)
straights = 0
# 按顺序处理每个可能的起始点
for start in range(1, 12): # 顺子最大到K(13),起始点最大为11
while True:
# 尝试组成从start开始的顺子
length = 3 # 顺子最小长度为3
# 检查能否组成更长顺子
current_jokers =okers = jokers
can_form = True
aapoker官方下载中心for i in range(start, start + length):
if freq[i] > 0:
freq[i] -= 1
elif current_jokers > 0:
current_jokers -= 1
else:
can_form = False
break
if can_form:
straights += 1
jokers = current_jokers
else:
break
return straights
# 测试
test_cards = [1, 2, 3, 4, 5, 6, 0, 0] # 1-6 + 两个王
print(f"最多可以组成 {max_straights(test_cards)} 个顺子")
问题一:
问题二:
这两个问题考察了以下算法技能:
1. 数组操作:排序、遍历
2. 逻辑推理:间隔计算、条件判断
3. 贪心思想:局部最优解构成全局最优解
4. 边界情况处理:重复数字、王牌使用
掌握这些问题有助于提升在华为机试中的表现!