zoukankan      html  css  js  c++  java
  • 面试题61:扑克牌中的顺子(C++)

    题目地址:https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/

    题目描述

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

    题目示例

    示例 1:

    输入: [1,2,3,4,5]
    输出: True

    示例 2:

    输入: [0,0,1,2,5]
    输出: True

    解题思路

    构成顺子条件:

    • 除大小王之外,其余牌数均未出现重复的情况,可通过判断数组相邻元素解决;
    • 5张牌中的最大牌 - 最小牌 < 5(大小王除外)

    思路1:简单排序。我们首先对拿到的数组nums进行排序,这样扑克牌就有序了,然后思考构成顺子的条件,我们发现可以通过大小王的张数来判断,即两张牌之间需要多少张大小王来填补,因为大小王0可代表任何牌数,所以可填充顺子中缺少的数,如果需要填补的大小王数量小于或等于已有大小王的张数,则表示能够构成顺子,返回true,否则,不能构成顺子,返回false。例如,扑克牌顺序0,0,1,5,6;其中,扑克牌1和扑克牌5之间需要5-1=4张大小王来填补,但扑克牌中却只有两张大小王(即两个0),所以它不能构成顺子。

    思路2:对思路1进行优化,数组排序之后,可得5张牌中的最大牌,以及最小牌(大小王除外),若最大牌 - 最小牌 < 5,则可构成顺子,返回true,否则,不能构成顺子,返回false。

    思路3:哈希表。使用哈希表判断除0之外是否有重复的牌数,如果没有,则判断(最大牌数 - 最小牌数)是否小于5,若小于,则构成顺子,返回true,否则,表示不能构成顺子,返回false。

    程序源码

    排序

    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            if(nums.size() == 0) return false;
            int cnt = 0; //统计大小王个数
            sort(nums.begin(), nums.end()); //数组排序,便于发现重复元素
            for(int i = 0; i < nums.size() - 1; i++)
            {
                if(nums[i] == 0) 
                    cnt++; //大小王个数统计
                else if(nums[i] == nums[i + 1]) 
                    return false; //除过大小王为0重复外,其余重复均不能构成顺子,返回false
                else
                    cnt -= (nums[i + 1] - nums[i] - 1); //相邻两张牌之间需要多少张大小王
            }
            return cnt >= 0; //构成顺子条件:大小王张数大于等于相邻两张牌之间的牌数
        }
    };

    排序优化(最大值 - 最小值 < 5)

    case1:

    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            if(nums.size() == 0) return false;
            sort(nums.begin(), nums.end());
            int cnt = 0; //统计大小王个数
            for(int i = 0; i < nums.size() - 1; i++)
            {
                if(nums[i] == 0) cnt++; //大小王张数
                if(nums[i + 1] == nums[i] && nums[i] != 0) return false;
            }
            return nums[4] - nums[cnt] < 5; //5张牌构成顺子条件:最大牌 - 最小牌 < 5
        }
    };

    case2:

    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            if(nums.size() == 0) return false;
            sort(nums.begin(), nums.end());
            for(int i = 0; i < nums.size() - 1; i++)
            {
                if(nums[i] != 0)
                {
                    if(nums[i] == nums[i + 1]) return false;
                    if(nums[4] - nums[i] >= 5) return false;
                }
            }
            return true;
        }
    };

    哈希表

    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            if(nums.size() == 0) return false;
            unordered_map<int, bool> joker_num;
            int max_joker = -1, min_joker = 14;
            for(int num:nums)
            {
                if(num!=0) 
                {
                    if(joker_num.find(num) != joker_num.end()) return false;
                    joker_num[num]=true;
                    max_joker = max(max_joker, num);
                    min_joker = min(min_joker, num);
                }
            }
            return max_joker - min_joker < 5;
        }
    };
    ----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
  • 相关阅读:
    MyBatis简介
    JDBC报错:Cannot find class: com.mysql.jdbc.Driver
    进程,线程,协程
    mamp提示 more elements...
    获取html页面的参数
    php基础函数
    返回接口
    生成订单号
    xml转数组
    判断是否是微信浏览器
  • 原文地址:https://www.cnblogs.com/wzw0625/p/12860165.html
Copyright © 2011-2022 走看看