【数学知识】剑指 Offer 61. 扑克牌中的顺子

本问题对应课程链接:剑指offer刷题第三期

要求:
1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。
2、给出你代码所用的时间复杂度和空间复杂度

共以下 25 个回答

  • 九号球 普通 2023年11月24日 下午10:38

    “`java
    注意重复也不行
    class Solution {
    public boolean checkDynasty(int[] places) {
    int zeroCount = 0;
    Arrays.sort(places);
    int period = 0;
    for (int i = 0; i < 4; i++) { if (places[i] == 0) { zeroCount++; continue; } if (places[i] == places[i + 1]) { return false; } period += places[i + 1] - places[i] - 1;

        }
        if (zeroCount >= period){ 
            return true;
        }
        return false;
    }
    

    }

    0 赞同 0 条回复
  • 招舟子 普通 2023年9月7日 下午6:06

    class Solution {
    public boolean isStraight(int[] nums) {
    int j = 0;
    Arrays.sort(nums);
    for(int i=0;i<nums.length-1;i++){
    if(nums[i]0){
    j++;
    }else if(nums[i]
    nums[i + 1]){
    return false;
    }
    }
    return nums[4]-nums[j]<5;
    }
    }
    复杂度o(nlogn)

    0 赞同 0 条回复
  • jhfuture 普通 2023年8月26日 下午10:25

    “`java
    class Solution {
    public boolean isStraight(int[] nums) {
    // 两个条件
    // 1.不包含重复数,0除外
    // 2.max-min<5,分析一下,会有5张牌,如果最大的-min=5,那他们之间一定相隔 4 张牌,那就不可能构成顺子了。
    Set re=new HashSet<>();
    int max=-1,min=14;
    for(int i=0;i

    0 赞同 0 条回复
  • mpweixin用户 普通 2023年8月2日 上午10:01
    java
    class Solution {
        public boolean isStraight(int[] nums) {
            Set<Integer> repeat = new HashSet<>();
            int max = 0;
            int min = 14;
            for(int num : nums) {
                if(num == 0) continue;
                max = Math.max(num, max);
                min = Math.min(num, min);
    
                if(repeat.contains(num)) {
                    return false;
                }
                repeat.add(num);
            }
    
            if((max - min) < 5) {
                return true;
            }
            return false;
        }
    }
    

    使用了set空间复杂度是O(5), 遍历了数组时间复杂度是O(5)

    0 赞同 0 条回复
  • 屠龙手段 普通 2023年7月23日 下午10:16

    排序 + 遍历,纯规则。时间复杂度O(nlogn) 空间复杂度O(1)

    class Solution:
        def isStraight(self, nums: List[int]) -> bool:
            nums.sort()
            cnt = 0
            for i in range(4):
                if nums[i] != 0:
                    if nums[i+1] == nums[i]:
                        return False
                    if nums[i+1] != nums[i] + 1:
                        cnt -= nums[i+1] - nums[i] - 1
                else:
                    cnt += 1
            return cnt >= 0
    
    0 赞同 0 条回复
  • 憨憨 永久会员 2023年7月20日 下午12:10

    桶排序找开始的位置,然后通过0的个数以及总个数来判断顺字

    class Solution {
        public boolean isStraight(int[] nums) {
            int[] arr = new int[14];
            for(int a : nums){
                arr[a] ++;
            }
            int sum = arr[0];
            int start = 1;
            for(int i = 1;i < 14; i++){
                if(arr[i]>1)return false;//
                if(arr[i]==1){
                    start = i;
                    break;
                }
            }
            int ans = 0;
            while(start < 14){
                if(arr[start]==1){
                    start++;
                    ans++;
                    continue;
                }
                if(arr[start]>1)return false;//
                if(arr[start] == 0&& sum > 0){
                    sum--;
                    ans++;
                    start++;
                }else{
                    break;
                }
            }
    
            return ans == 5 || start == 14;
        }
    }
    
    0 赞同 0 条回复
  • WhyNot 普通 2023年7月19日 下午10:13
    int cmp(const void* a, const void* b) {
        return *(int*)a - *(int*)b;
    }
    
    bool isStraight(int* nums, int numsSize) {
        int joker = 0;
        qsort(nums, numsSize, sizeof(int), cmp);
        for (int i = 0; i < numsSize - 1; i++) {
            if (nums[i] == 0) {
                joker++;
            } else if (nums[i] == nums[i + 1]) {
                return false;
            }
        }
        return nums[4] - nums[joker] < 5;
    }
    

    时间复杂度为O(n*logn)
    空间复杂度为O(1)

    0 赞同 0 条回复
  • 怀瑾 永久会员 2023年7月19日 下午3:35

    “`C++
    bool isStraight(std::vector& nums) {
    // 排序牌组
    std::sort(nums.begin(), nums.end());

    // 统计0的个数
    int zeros = 0;
    for (int num : nums) {
        if (num == 0)
            zeros++;
    }
    
    // 统计非0数字之间的间隔数
    int gaps = 0;
    for (int i = zeros; i < nums.size() - 1; i++) {
        // 若有对子,则不可能是顺子
        if (nums[i] == nums[i + 1])
            return false;
    
        gaps += nums[i + 1] - nums[i] - 1;
    }
    
    // 判断0的个数是否足够填补间隔
    return gaps <= zeros;
    

    }

    “`

    0 赞同 0 条回复
  • 名字什么的好麻烦 普通 2023年7月17日 下午9:25

    排序+遍历

    class Solution {
        public boolean isStraight(int[] nums) {
            Arrays.sort(nums);
            int sum=0;
            for(int i=0;i<4;i++){
                if(nums[i]==0)
                    sum++;
                else if(nums[i]==nums[i+1])
                    return false; 
            }
            return nums[4]-nums[sum]<5;
        }
    }
    
    0 赞同 0 条回复
  • 江畅 普通 2023年7月16日 下午2:05
    // 扑克牌中的顺子
    // 时间复杂度 O(N)
    // 空间复杂度 O(N)
    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            unordered_set<int> numSet;
            int maxVal = INT_MIN;
            int minVal = INT_MAX;
    
            for (int num : nums) {
                if (num == 0) { continue; }
                if (numSet.count(num)) { return false; }
                numSet.insert(num);
    
                maxVal = max(maxVal, num);
                minVal = min(minVal, num);
            }
            return maxVal - minVal <= 4;
        }
    };
    
    0 赞同 0 条回复
  • 哈哈哈哈开开心心 普通 2023年7月16日 上午5:10
    class Solution:
        def isStraight(self, nums: List[int]) -> bool:
            cardSet = set()
            maxCard = -1
            minCard = 14
    
            for i in range(5):
                if nums[i] == 0:
                    continue
    
                if nums[i] in cardSet:
                    return False
    
                cardSet.add(nums[i])
                maxCard = max(maxCard, nums[i])
                minCard = min(minCard, nums[i])
    
            return maxCard - minCard < 5
    
    

    忽略0

    0 赞同 0 条回复
  • BOZ 普通 2023年7月15日 下午5:52

    【思路】要形成顺子的条件为:1. 5张牌中最大最小之差小于5;2. 5张牌中不能有重复。其中0需要特殊处理
    【复杂度】为了检测重复用到了c++ STD库的set,所以时间空间复杂度都为O(nlogn)

    #include <set>
    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            std::set<int> unique;
            int max = 0, min = 14;
            for (auto &n: nums) {
                if (!n) continue;
                if (unique.find(n) != unique.end()) return false;
                unique.insert(n);
                max = std::max(max, n);
                min = std::min(min, n);
            }
            return max - min < 5;
        }
    };
    
    0 赞同 0 条回复
  • 花老爷 普通 2023年7月15日 上午10:26

    排序
    时间:O(nlogn)
    空间:O(1)

    class Solution {
        public boolean isStraight(int[] nums) {
            Arrays.sort(nums);
            int king = 0;
            for (int i = 0; i < nums.length - 1; i++) {
                int diff = nums[i + 1] - nums[i];
                if (nums[i] == 0) {
                    king++;
                // 当diff = 0即后面牌面跟前面一样时不可能;当diff > king + 1时,中间的差值大小王已经不能弥补,不可能。
                } else if (diff == 0 || diff > king + 1) {
                    return false;
                // 当diff = 1时,相当于continue,大于1时用大小王来弥补
                } else {
                    king -= diff - 1;
                }
            }
            return true;
        }
    }
    
    0 赞同 0 条回复
  • Ming 普通 2023年7月13日 下午2:58
    class Solution {
        public boolean isStraight(int[] nums) {
            // 集合
            int min = 14;
            int max = 0;
            Set<Integer> set = new HashSet<>();
            for(int i = 0; i < nums.length; i++) {
                // 大小王跳过
                if(nums[i] == 0) continue;
                // 重复必然不是顺子
                if(set.contains(nums[i])) return false;
                set.add(nums[i]);
                max = Math.max(max,nums[i]);
                min = Math.min(min,nums[i]);
            }
            return max - min < 5;
        }
    }
    
    0 赞同 0 条回复
  • Dsjh 普通 2023年7月11日 上午11:52

    MY

    不是最优

    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            int num = 0;
            bool ans = true;
            sort(nums.begin(),nums.end());
            for(int i=0;i<nums.size()-1;i++){
                if(nums[i]==0)
                    num++;
                else{
                    if(nums[i] == nums[i+1])
                        return false;
                }
            }
            return nums[4]-nums[num] < 5;
        }
    };
    
    0 赞同 0 条回复
  • Vow the vow。 普通 2023年7月11日 上午11:04

    顺子的概念,换成数学条件

    HashSet<Integer> hashSet = new HashSet<>();
        public boolean isStraight(int[] nums) {
            int max = 0, min = 14;
            for(int num : nums){
                if(num == 0) continue;
                max = Math.max(max,num);
                min = Math.min(min,num);
                if(hashSet.contains(num)) return false;
                hashSet.add(num);
            }
            return max - min < 5;
        }
    
    0 赞同 0 条回复
  • 局外人 普通 2023年7月11日 上午9:47

    思路:只有5张牌,要使其为顺子,则最大值与最小值之差,应该小于5
    时间复杂度:O(n) 空间复杂度:O(n)

    class Solution {
        public boolean isStraight(int[] nums) {
            int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
    
            Set<Integer> set = new HashSet<>();
    
            for(int num:nums){
                if(num==0)  continue;
    
                if(set.contains(num))   return false;
    
                set.add(num);
    
                max = Math.max(max, num);
                min = Math.min(min, num);
    
            }
    
            return max-min<=4;
        }
    }
    
    0 赞同 0 条回复
  • 行动派小彩笔 普通 2023年7月10日 下午11:48
    // 最大值和最小值不能超过5
    // 且元素不能有重复
    // 时间复杂度O(n) 空间复杂度O(n)
    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            unordered_set<int> s;
            int min = 14,max = 0;
            for(auto num:nums)
            {
                if(num == 0) continue;
                if(s.count(num)) return false;
                s.insert(num);
                min = ::min(num,min);
                max = ::max(num,max);
            }
            return max-min<5;
        }
    };
    
    0 赞同 0 条回复
  • mpweixin用户 永久会员 2023年7月10日 下午11:05
    //时间O(n) 空间O(n)
    public boolean isStraight(int[] nums) {
            Set<Integer> set = new HashSet();
            int count = 0;
            int min = Integer.MAX_VALUE;
            int max = Integer.MIN_VALUE;
            for(int i = 0;i < nums.length;i++){   
                if(nums[i] == 0){
                    //零单独处理
                    count++;
                }else{
                    //不是零
                    set.add(nums[i]);
                    if(nums[i] > max){
                        max = nums[i];
                    }
                    if(nums[i] < min){
                        min = nums[i];
                    }
                }
    
            }
            if((set.size() + count) != 5){    
                //有重复
                return false;
            }
            if((max - min) >= 5){
                return false;
            }
    
            return true;
        }
    
    0 赞同 0 条回复
  • Jerry 普通 2023年7月10日 下午10:55
    // Set + 差值(max - min)
    class Solution {
        public boolean isStraight(int[] nums) {
            Set<Integer> set = new HashSet<>();
            int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
            for (int num  : nums) {
                if (num == 0) continue; //遇到大小王,则跳过
                if (set.contains(num)) return false; //顺子不可能有重复的数字
                set.add(num);
    
                //计算 max,min
                max = Math.max(max, num);
                min = Math.min(min, num);
            }
            return max - min <= 4; //判断是否是顺子,只需判断 max - min <= 4 即可
        }
    }
    

    时间复杂度:O(n)
    空间复杂度:O(n)

    0 赞同 0 条回复
  • 张君雅小妹妹 普通 2023年7月10日 下午10:50

    时间复杂度:O(n)
    空间复杂度:O(n)

    class Solution {
        public boolean isStraight(int[] nums) {
            /*
             * 成为一个顺子需要满足两个条件
             *     1. 没有重复的数,大小王除外
             *     2. 最大的数和最小的数的差小于5
             */
    
             Set<Integer> set = new HashSet<>();
             int max = -1, min = 20;
             for(int i = 0; i < nums.length; i++){
                 if(nums[i] == 0) continue;
                 if(set.contains(nums[i])) return false;
                 set.add(nums[i]);
                 max = Math.max(max, nums[i]);
                 min = Math.min(min, nums[i]);
             }
             return max - min < 5;
        }
    }
    
    0 赞同 0 条回复
  • yxy 普通 2023年7月10日 下午7:10

    时间复杂度O(n)

    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            sort(nums.begin(),nums.end());
            int numOfZero = 0;
            int last = 0;
            for(int i=0;i<5;i++)
            {
                if(nums[i]==0)
                {
                    numOfZero++;
                }
                else
                {
                    cout<<last<<" ";
                    if(last==0)
                    {
                        last=nums[i];
                        continue;
                    }
                    if(nums[i]!=last+1)
                    {
                        if(numOfZero==0)
                            return false;
                        numOfZero--;
                        last++;
                        i--;
                    }
                    else
                        last=nums[i];
                }
            }
            return true;
        }
    };
    
    0 赞同 0 条回复
  • 小吕 普通 2023年7月10日 下午5:06

    c++实现
    bool isStraight(vector& nums) {
    set
    set;
    int maxx = -1,minx = 20;
    for(int i = 0;i<nums.size();i++)
    {
    if(nums[i]0)continue;
    if(set.count(nums[i]))return false;
    set.insert(nums[i]);
    maxx = max(nums[i],maxx);
    minx = min(nums[i],minx);
    }
    return maxx-minx<5;
    }

    0 赞同 0 条回复
  • 张开怀 普通 2023年7月10日 下午3:45
    class Solution{
    public:
           bool isStraight(vector<int>& nums){
                  // 不存在相同的数字,大小王除外
                  // 最大值和最小值的差值小于5,大小王除外
                  set<int> s;
                  int max_num = -1, min_num = 20;
                  for(int i=0; i<nums.size(); i++){
                         // 大小王
                         if(num[i]==0){
                                continue;
                         }
                         // 是否存在相同的数字
                         if(s.count(nums[i])){
                                return false;
                         }
                         s.insert(nums[i]);
                         max_num = max(max_num, nums[i]);
                         min_num = min(min_num,nums[i]);
                  }
                  return max_num - min_num < 5;
           }
    };
    

    时间复杂度:O(n)
    空间复杂度:O(n)

    0 赞同 0 条回复
  • Yodl. 普通 2023年7月10日 下午3:00
    //时间复杂度O(n)  空间复杂度O(1)
    class Solution {
    public:
        bool isStraight(vector& nums) {
            int cnt0 = 0;
            sort(nums.begin(), nums.end());
            for(auto x:nums){
                if(x == 0) cnt0++;//利用x遍历并获得nums容器中的每一个值,但是x无法影响到nums容器中的元素
                else break;
            }
            for(int i = cnt0 + 1; i < nums.size(); i++){
                int cur = nums[i] - nums[i - 1];
                if(cur > 1) cnt0 -= (cur - 1);
                else if(cur == 0) return false;
                else continue;
            }
            return cnt0 >=0;
        }
    };
    
    0 赞同 0 条回复

# 回答此问题

后才能回答