2019.1.3 《剑指Offer》从零单刷个人笔记整理(66题全)目录传送门
这道题是比较有意思的实际问题,相当于扑克牌赌博游戏的一个方法。做法有两种,思路大体相同:
方法一:升序排序,统计王牌个数,统计数字前后间隔数目,若两者相等则为顺子。(排除重复牌)
方法二:升序排序,统计王牌个数,利用动态规划的方法,从第一张非王牌开始,若下一张牌不等于当前牌+1,则消耗一张王卡。若发生重复或超量使用王卡则不是顺子。
题目描述
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这五张牌是不是连续的。其中,大\小王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。
注:本题王牌多2张,一共4张王牌。
Java实现(方法二):
/**
*
* @author ChopinXBP
* 从扑克牌中随机抽5张牌,判断是不是一个顺子,即这五张牌是不是连续的。
* 其中,大\小王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。
* 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。
*
*/
import java.util.Arrays;
public class isContinuous_43 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] numbers = {0, 3, 5, 7, 4};
System.out.println(isContinuous(numbers));
}
public static boolean isContinuous(int [] numbers) {
if(numbers == null || numbers.length != 5)return false;
Arrays.sort(numbers); //数组排序
int zeronum = 0; //记录0值(王牌)个数
int i = 0;
while(i < 4 && numbers[i] == 0) {
zeronum++;
i++;
}
int locnum = numbers[zeronum]; //取第一张非王牌作为当前牌
for(i = zeronum + 1; i < 5; i++) {
//若下一张牌等于当前牌,则发生重复,直接结束返回false
if(numbers[i] == locnum) {
return false;
}
//若下一张牌等于当前牌+1,则当前牌+1并继续
else if(numbers[i] == locnum + 1) {
locnum++;
}
//若下一张牌不等于当前牌或当前牌+1,则消耗一张王卡,保持当前位置,当前牌+1并继续
else {
zeronum--;
locnum++;
i--;
}
if(zeronum < 0) return false; //若超量消耗王卡,直接结束返回false
}
return true;
}
}
C++实现示例(方法一):
//考略到顺子的特性,最大值和最小值之差绝对为4,
//然而又有大小王的存在,所以a[4]-a[jokers] <=4
class Solution {
public:
bool IsContinuous( vector<int> numbers ) {
int len=numbers.size();
if(len!=5) return false;
sort(numbers.begin(),numbers.end());
int jokers=0;//计算王的数目
for(int i=0;i<5&&numbers[i]==0;i++){
jokers++;
}
if(jokers>4) return false;
for(int i=jokers+1;i<5;i++){
if(numbers[i]==numbers[i-1])//判断对子的存在
return false;
}
int dis=numbers[4]-numbers[jokers];
if(dis<=4) return true;
return false;
}
};
测试代码:
// ====================测试代码====================
void Test(char* testName, int* numbers, int length, bool expected)
{
if(testName != NULL)
printf("%s begins: ", testName);
if(IsContinuous(numbers, length) == expected)
printf("Passed.\n");
else
printf("Failed.\n");
}
void Test1()
{
int numbers[] = {1, 3, 2, 5, 4};
Test("Test1", numbers, sizeof(numbers) / sizeof(int), true);
}
void Test2()
{
int numbers[] = {1, 3, 2, 6, 4};
Test("Test2", numbers, sizeof(numbers) / sizeof(int), false);
}
void Test3()
{
int numbers[] = {0, 3, 2, 6, 4};
Test("Test3", numbers, sizeof(numbers) / sizeof(int), true);
}
void Test4()
{
int numbers[] = {0, 3, 1, 6, 4};
Test("Test4", numbers, sizeof(numbers) / sizeof(int), false);
}
void Test5()
{
int numbers[] = {1, 3, 0, 5, 0};
Test("Test5", numbers, sizeof(numbers) / sizeof(int), true);
}
void Test6()
{
int numbers[] = {1, 3, 0, 7, 0};
Test("Test6", numbers, sizeof(numbers) / sizeof(int), false);
}
void Test7()
{
int numbers[] = {1, 0, 0, 5, 0};
Test("Test7", numbers, sizeof(numbers) / sizeof(int), true);
}
void Test8()
{
int numbers[] = {1, 0, 0, 7, 0};
Test("Test8", numbers, sizeof(numbers) / sizeof(int), false);
}
void Test9()
{
int numbers[] = {3, 0, 0, 0, 0};
Test("Test9", numbers, sizeof(numbers) / sizeof(int), true);
}
void Test10()
{
int numbers[] = {0, 0, 0, 0, 0};
Test("Test10", numbers, sizeof(numbers) / sizeof(int), true);
}
// 有对子
void Test11()
{
int numbers[] = {1, 0, 0, 1, 0};
Test("Test11", numbers, sizeof(numbers) / sizeof(int), false);
}
// 鲁棒性测试
void Test12()
{
Test("Test12", NULL, 0, false);
}
int _tmain(int argc, _TCHAR* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();
Test9();
Test10();
Test11();
Test12();
return 0;
}
#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#