• 剑指 Offer 61. 扑克牌中的顺子


    在这里插入图片描述
    用一个长度为14的数组记录,每个值的个数,遍历数组记录的同时排除值重复的情况

    遍历记录个数的数组:

    • 若没有当前值,且没joker,则返回false
    • 若没有当前值,有joker,则使用一个joker,joker的数量减1,继续遍历
    • 遍历完成都没返回,说明可以组成顺子
    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            int arr[14] = { 0 };
            for (int num : nums) {
                arr[num]++;
            }
            int start = 1;
            int joker = arr[0];
            while (start < 14) {
                if (arr[start] == 0) {
                    // 没有当前值,往后找
                    start++;
                }
                else if (arr[start] == 1) {
                    // 找到一个值了,开始查看后4个能否组成顺子
                    break;
                }
                else {
                    // 值重复,不能组成顺子
                    return false;
                }
            }
            int cur = start;
            while (cur <= start + 4 && cur < 14) {
                if (arr[cur] > 1 || (arr[cur] == 0 && joker == 0)) {
                    // 有重复的 || 没有当前值,没joker了
                    return false;
                }
                if (arr[cur] == 0 && joker > 0) {
                    // 没有当前值,有joker
                    joker--;
                }
                cur++;
            }
            // 5个遍历完,值都存在,可以组成顺子
            return true;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    集合 Set + 遍历

    • 遍历五张牌,遇到 joker(即 0 )直接跳过。
    • 判别重复: 利用 Set 实现遍历判重, Set 的查找方法的时间复杂度为 O(1) ;
    • 获取最大 / 最小的牌: 借助辅助变量 max 和 min ,遍历统计即可
    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            unordered_set<int> st;
            int max_ = nums[0];   // 这里的最大最小值,指的是除了jokere以外的最大最小值
            int min_ = 13;        // 最小值不能为0,初始化为最大的13
            for (int num : nums) {
                if (num == 0) {
                    continue;
                }
                if (st.count(num) > 0) {
                    // 重复,不能组成顺子
                    return false;
                }
                st.insert(num);
                max_ = max(max_, num);
                min_ = min(min_, num);
            }
            // 不重复,最大值-最小值 < 5,必能组成顺子
            return max_ - min_ < 5;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    排序 + 遍历

    • 判别重复: 排序数组中的相同元素位置相邻,因此可通过遍历数组,判断 nums[i] = nums[i + 1] 是否成立来判重。
    • 获取最大 / 最小的牌: 排序后,数组末位元素 nums[4] 为最大牌;元素 nums[joker] 为最小牌,其中 joker 为大小王的数量
    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            sort(nums.begin(), nums.end(), less<int>());
            int joker = 0;
            for(int i = 0; i < 5; i++){
                if(nums[i] == 0){
                    joker++;
                }else if(i < 4 && nums[i] == nums[i+1]){
                    return false;
                }
            }
            if (joker == 5) {
                return true;
            }
            // 不重复,最大值-最小值 < 5,必能组成顺子
            return nums[4] - nums[joker] < 5;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            sort(nums.begin(), nums.end(), less<int>());
            int joker = 0;
            for(int i = 0; i < 4; i++){
                if(nums[i] == 0){
                    joker++;
                }else if(nums[i] == nums[i+1]){
                    return false;
                }
            }
            // 不重复,最大值-最小值 < 5,必能组成顺子
            return nums[4] - nums[joker] < 5;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    集合 Set / 排序,清晰图解

  • 相关阅读:
    个人以及企业用户如何选择合适的阿里云服务器?
    为什么要学习更加现代的命令行工具?
    虚拟机基本使用 IV
    C4BUILDER—用于构建C4模型图的Web项目
    计算机毕业设计django基于python金太阳家居电商平台
    重学设计模式之-组合模式-mybatis-SqlNode使用组合模式
    Qt QSS基本属性样式表半通关
    【U盘检测】为了转移压箱底的资料,买了个2T U盘检测仅仅只有47G~
    采集数据重复解决方法
    JavaEE-多线程-CAS
  • 原文地址:https://blog.csdn.net/qq_42500831/article/details/126375213