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

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

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

共以下 26 个回答

  • Gg 普通 2023年5月2日 下午10:17
    class Solution {
        public boolean isStraight(int[] nums) {
            // 满足顺子有两条件。不重复、max - min < 5
            Set<Integer> set = new HashSet<>();
            int max = 0,min = 14;
            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);
            }
            if(max - min >= 5){
                return false;
            }
            return true;
        }
    }
    
    0 赞同 0 条回复
  • 宁 永久会员 2023年3月15日 上午11:20

    主要是规则的转换

    class Solution {
        public boolean isStraight(int[] nums) {
            //转换成 最大值最小值相差小于5,并且没有重复元素(除大小王)
            Set<Integer> set = new HashSet<>();
            int min = 13;
            int max = 1;
            for(int i = 0; i < nums.length; i++){
                if(nums[i] == 0) continue;
                if(set.contains(nums[i])) return false;
                set.add(nums[i]);
                min = Math.min(min, nums[i]);
                max = Math.max(max, nums[i]);
            }
            return max - min < 5;
        }
    }
    
    0 赞同 0 条回复
  • PatNick 普通 2023年1月12日 下午4:57
    # 找到重复的数、最大值、最小值
    def isStraight(nums):
        l = []
        # 把最大值设为最小数,最小值设为最大数
        max_ = -float('inf')
        min_ = float("inf")
        for _ in nums:
            if _ in l and _ != 0:
                return False
            if not _ in l:
                l.append(_)
            # 最大值与最小值只在非零情况下更新
            if _ != 0:
                max_ = max(max_,_)
                min_ = min(min_,_)
    
        if max_-min_ < 5:
            return True
        return False
    
    
    0 赞同 0 条回复
  • lucca 普通 2023年1月11日 下午11:48

    时间O(N) 空间O(N)

    class Solution {
        // 时间O(N) 空间O(N)
        public boolean isStraight(int[] nums) {
            HashSet<Integer> s = new HashSet<>();
            int min = 0, max = 0;
            for (int num : nums) {
                if (num == 0) continue;
    
                if (s.contains(num)) return false;
                s.add(num);
    
                if (min == 0 || num < min) min = num;
                if (max == 0 || num > max) max = num;
            }
            return max - min < 5;
        }
    }
    

    时间O(NlogN) 空间O(1)

    class Solution {
        // 时间O(NlogN) 空间O(1)
        public boolean isStraight(int[] nums) {
            int cnt = 0;
            Arrays.sort(nums);
            while (cnt < nums.length && nums[cnt] == 0) cnt++;
            for (int i = cnt + 1; i < nums.length; i++) {
                if (nums[i] == nums[i-1]) return false;
            }
            return nums[4] - nums[cnt] < 5;
        }
    }
    
    0 赞同 0 条回复
  • xye 普通 2022年12月8日 下午12:24
    func isStraight(nums []int) bool {
        sort.Ints(nums)
        count := 0
        for i := 0; i < len(nums); i++ {
            if nums[i] == 0 {
                count++
            }else if i + 1 < len(nums) && nums[i + 1] == nums[i] {
                return false
            }
        }
        return nums[4] - nums[count] < 5
    
    
    }
    
    

    时间O(NlogN) 空间O(1)
    排序

    0 赞同 0 条回复
  • yanshuojune 普通 2022年12月7日 上午12:12
    # 排序+遍历:排序之后判断最大减去0之后的最小值是否<5且无重复
            # 时间:排序O(nlogn) 空间:O(1)
            nums.sort()
            count = 0
            for i in range(4):
                if nums[i] == 0:
                    count += 1
                elif nums[i] == nums[i+1]:
                    return False
            return nums[-1] - nums[count] < 5
    
    0 赞同 0 条回复
  • symbol 普通 2022年12月3日 上午7:27
    func isStraight(nums []int) bool {
       sort.Ints(nums) //先排序
       joker:=0
       for i:=0;i<4;i++{
           if nums[i]==0{
               joker++ //记录joker数量
           } else {
               if nums[i]==nums[i+1]{  //除了0之外,有相同的元素直接返回false
                   return false
               }
           }
       }
       return nums[4]-nums[joker]<5  
    }
    
    
    0 赞同 0 条回复
  • 🚲南下 普通 2022年11月30日 下午8:27
    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            //两个条件,max-min<5,除了大小王,无重复
            sort(nums.begin(),nums.end());
            int min = nums[nums.size()-1];
            int max = nums[nums.size()-1];
            int count = 0;//统计大小王的个数
            set<int> shun;
            for(int i = 0; i < nums.size();i++){
                if(nums[i]==0) {
                    count++;
                }
                else {
                    if(nums[i] < min) min = nums[i];
                    shun.insert(nums[i]);
                }
            }
    
            if(count+shun.size()==5 && max-min<5) return true;
            else return false;
        }
    };
    
    0 赞同 0 条回复
  • 庄重 普通 2022年11月26日 下午11:29
    // 思路1--使用排序-->时间复杂度O(nlogn)--非最优解
    //     大小王除外 [0,0,1,2,5] 
    //     1.进行排序,相邻元素之间的差值满足1,
    //     2.不满足0为false,大于1看被大小王填充
    // 思路2--如果要成为一个顺子,则需要 满足两个条件--最优解
    //     1、不存在有重复的数,大小王除外
    //     2、最大值 - 最小值 < 5,大小王除外
    class Solution {
    public:
        bool isStraight(vector<int>& nums) {
            //set集合,不允许重复且排序为从小到大,可以重载 () 符号进行自定义排序
            set<int> myset;
            for(int i = 0; i < nums.size(); ++i){
                if(nums[i] == 0) continue;
    
                if(myset.find(nums[i]) != myset.end()){
                    return false;
                }
                myset.insert(nums[i]);
            }
            return (*myset.rbegin()) - (*myset.begin()) < 5;//使用rbegin()需要使用reverse_iterator
    
            //return ((*myset.end()) - (*myset.begin())) < 5;
            //错误的,end()的真实指向是set集合中最后一个元素的下一个迭代器,并且存储的是set集合的大小,但是vs2022不允许访问*my.end(),直接出现引用错误
            //cout << *myset.end()也是不允许的,因此网上一些对于end()的使用现在是错误的,需要注意
            //因此出现了反向迭代器来解决这个问题,rbegin的指向为set的最后一个元素
        }
    };
    //时间复杂度O(n)
    //空间复杂度O(n)
    
    0 赞同 0 条回复
  • y 普通 2022年11月20日 下午2:33
    var isStraight = function(nums) {
      // 1、不存在有重复的数,大小王除外
     // 2、最大值 - 最小值 < 5,大小王除外
      let set = new Set();
      let min = 20, max = -1;
      for (let i = 0; i< nums.length; i++) {
          if (nums[i] === 0) continue;
          if (set.has(nums[i])) return false;
          set.add(nums[i])
          max = Math.max(nums[i], max);
          min = Math.min(nums[i], min);
      }
      return max - min < 5;
    };
    
    0 赞同 0 条回复
  • lobort 普通 2022年11月19日 下午5:19
    class Solution {
        public boolean isStraight(int[] nums) {
            //总体思路就是找到最大值和最小值 判断相减是否小于5
            Arrays.sort(nums);
            int zero = 0;
            for(int i = 0; i < 4; i ++){
                if(nums[i] == 0){
                    zero++;
                }else if(nums[i] == nums[i+1]){
                    return false;
                }
            }
            return nums[4] - nums[zero] < 5;
    
            int min = 14, max = 0;
            Set<Integer> set = new HashSet<Integer>();
            for(int num : nums){
                if(num == 0){
                    continue;
                }
                if(set.contains(num)){
                    return false;
                }
                min = Math.min(num,min);
                max = Math.max(num,max);
                set.add(num);
            }
            return max - min < 5;
        }
    }
    
    0 赞同 0 条回复
  • 你有点可爱喔 普通 2022年11月18日 下午2:13
    class Solution {
        public boolean isStraight(int[] nums) {
            //满足的条件、不能有重复的数字
            // 最大值-最小值<5
            Set<Integer> set = new HashSet<>();
            int max = -1,min = 20;
            for (int i = 0;i < nums.length;i++){
                //0:代表大王
                if (nums[i] == 0) continue;
                //有重复的直接返回false;
                if (set.contains(nums[i])) return false;
                //则添加在结合中
                set.add(nums[i]);
                //在循环的过程中找出最大值与最小值;直至这个最大值-最小值的结果<5时。
                max = Math.max(nums[i],max);
                min = Math.min(nums[i],min);
            }
            return max-min<5;
    
        }
    }
    //时间复杂度O(n)
    
    0 赞同 0 条回复
  • @ 普通 2022年11月18日 上午10:38

    时间复杂度 O(1
    **空间复杂度 O(1) **

    class Solution {
    
        //排序+遍历
        public boolean isStraight(int[] nums) {
            int zero = 0;
            int t = 0;
    
            Arrays.sort(nums);
    
            for (int i = 0; i < nums.length - 1; i++) {
                if(nums[i + 1] <= nums[i] && nums[i + 1] != 0)
                    return false;
    
                if(nums[i] == 0){
                    zero++;
                    continue;
                }
    
    
                if(nums[i + 1] != nums[i] + 1)
                    t += nums[i + 1] - nums[i] - 1;
    
            }
    
            if(t > zero)
                return false;
    
            return true;
        }
    
        //大佬的最优解法
         public boolean isStraight(int[] nums) {
            Set<Integer> repeat = new HashSet<>();
            int max = 0, min = 14;
            for(int num : nums) {
                if(num == 0) continue; // 跳过大小王
                max = Math.max(max, num); // 最大牌
                min = Math.min(min, num); // 最小牌
                if(repeat.contains(num)) return false; // 若有重复,提前返回 false
                repeat.add(num); // 添加此牌至 Set
            }
            return max - min < 5; // 最大牌 - 最小牌 < 5 则可构成顺子
        }
    
    
    }
    
    0 赞同 0 条回复
  • 是梦终空 永久会员 2022年11月17日 上午2:27

    时间O(n)
    空间O(1)

    class Solution {
        public boolean isStraight(int[] nums) {
            int joker = 0;
            Arrays.sort(nums); //排序
            for(int i = 0; i < 4; i++) {
                if(nums[i] == 0) joker++;   //统计大小王 
                else if(nums[i] == nums[i + 1]) return false;   //相邻重复肯定false; 
            }   
            return nums[4] - nums[joker] < 5;       //只要最大牌-最小牌 < 5即可.
        }
    }
    
    0 赞同 0 条回复
  • 派大星 普通 2022年11月16日 下午9:19
    class Solution {
    //通过记录大小王(0)的个数来判断扑克牌可不可以成为顺子,一旦有两张牌相等直接返回false;
    //时间复杂度O(n^2)
    //空间复杂度O(1)
    //
         public boolean isStraight(int[] nums) {
            int sum = 0;
            for (int num : nums) {
                if(num == 0) sum ++;
            }
            if(sum >= 4)return true;
            for (int i = 0; i < nums.length; i++) {
                for (int j = 0; (j < nums.length - i) && j+1 < nums.length; j++) {
                    if(nums[j] > nums[j + 1]){
                        nums[j] = nums[j] ^ nums[j+1];
                        nums[j+1] = nums[j] ^ nums[j + 1];
                        nums[j] = nums[j] ^ nums[j+1];
                    }
                }
            }
    
            boolean b = is(nums,sum);
    
            return b;
        }
                             //       489 11 12
        public boolean is(int[] nums,int a){
            for (int i = a; (i < nums.length) && i+1 < nums.length; i++) {
                if(nums[i + 1] - nums[i] > a + 1 || nums[i] == nums[i + 1]){
                    return false;
                }
                if(nums[i] - nums[i + 1] > 1){
                    a = a - (nums[i + 1] - nums[i] - 1 );
                }
    
            }
            return true;
        }
    }
    
    0 赞同 0 条回复
  • 天然 普通 2022年11月16日 下午8:47

    玩赖皮,怎么能有3个王???,迫于无奈,统计王的个数,剩下非零数进行遍历

    class Solution:
        def isStraight(self, nums: List[int]) -> bool:
            nums.sort() #先排序
            i=0
            for num in nums:
                if num==0: i+=1 #统计0的个数
            if i==0: tem = 0  #没有王
            elif i==1: tem = 1 #一个王
            elif i==2: tem = 2 #二个
            elif i==3: tem = 3
            else: return True #大于3 直接真
            for k in range(tem,4):
                    if nums[k+1]-nums[k]>1:
                        i-=nums[k+1]-nums[k]-1  #看王的数量是否满足牌距
                    if nums[k+1]==nums[k]:return False  #相同返回假
            if i>=0:return True  #查看王的个数
            else: return False
    #O(n),空间复杂度O(1)
    
    0 赞同 0 条回复
  • 西西弗斯的石头 永久会员 2022年11月16日 下午3:12

    时间复杂度O(n),空间复杂度O(1)

    class Solution {
        public boolean isStraight(int[] nums) {
            Arrays.sort(nums);
            int sum = 0;
            for(int i = 0;i < nums.length;i++){
                if(nums[i] == 0) continue;
                if((i - 1) >= 0 && nums[i - 1] == nums[i]) return false;
                if((i - 1) >= 0 && nums[i-1] != 0) sum += (nums[i] - nums[i-1]);
            }
            if(sum < 5) return true;
            return false;
        }
    }
    
    0 赞同 0 条回复
  • Error 普通 2022年11月15日 下午10:10
    class Solution:
        def isStraight(self, nums: List[int]) -> bool:
            joker = 0
            nums.sort()
            for i in range(4):
                if nums[i] == 0:
                    joker += 1
                elif nums[i] == nums[i+1]:
                    return False
            return nums[4] - nums[joker] < 5
    

    时间复杂度 O(n)

    0 赞同 0 条回复
  • So 普通 2022年11月15日 下午4:07
    class Solution {
        public boolean isStraight(int[] nums) {
            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(nums[i], max);
                min = Math.min(nums[i], min);
            }
            return max - min < 5;
        }
    }
    

    时间:O(n),空间:O(n)

    0 赞同 0 条回复
  • 大宝子冲 永久会员 2022年11月15日 下午2:29
    class Solution {
        public boolean isStraight(int[] nums) {
            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;
        }
    }
    

    时间和空间复杂度都是O(n)

    0 赞同 0 条回复
  • just 普通 2022年11月15日 下午12:08

    //时间复杂度和空间复杂度都是n
    class Solution {
    public:
    bool isStraight(vector& nums) {
    unordered_set
    set;
    int l=15,r=-1;
    for(int i=0;i<nums.size();++i){
    if(nums[i]0) continue;
    else{
    l=min(l,nums[i]);
    r=max(nums[i],r);
    if(set.count(nums[i])) return false;
    set.insert(nums[i]);
    }
    }
    return r-l<5;

    }
    

    };

    0 赞同 0 条回复
  • 云雾里 普通 2022年11月14日 下午11:53
    class Solution {
        public boolean isStraight(int[] nums) {
            //排序
            Arrays.sort(nums);
            int joker=-1;
            for (int i = 0; i < nums.length-1; i++) {
                int now = nums[i];
                //0跳过
                if(now==0)continue;
                //和下个相同直接返回false
                if(now==nums[i+1]){
                    return false;
                }
                //记录第一个不是0的
                if(now!=0&&joker==-1){
                    joker=i;
                }
            }
            //最大值-最小值小于5即顺子
            return nums[4]-nums[joker]<5;
        }
    }
    
    0 赞同 0 条回复
  • 青木 普通 2022年11月14日 下午10:32
    /**
        先遍历一遍看是否有重复
        最大值最小值差值应小于5
    
        时间O(n^2)
        空间O(1)
     */
    class Solution {
        public boolean isStraight(int[] nums) {
            for(int i=0; i<4; i++){
                for(int j=i+1; j<5;j++){
                    if(nums[i] != 0 && nums[i] == nums[j]) return false;
                }
            }
    
            int minVal = 14;
            int maxVal = -1;
            for(int num : nums){
                if(num==0) continue;
                minVal = Math.min(minVal, num);
                maxVal = Math.max(maxVal, num);
            }
            return maxVal - minVal < 5;
        }
    }
    
    /**
        使用哈希,只用遍历一次
    
        时间O(n)
        空间O(n)
     */
    class Solution {
        public boolean isStraight(int[] nums) {
            Set set = new HashSet<>();
    
            int minVal = 14;
            int maxVal = -1;
            for(int num : nums){
                if(num==0) continue;
                minVal = Math.min(minVal, num);
                maxVal = Math.max(maxVal, num);
                if(set.contains(num)) return false;
                set.add(num);
            }
            return maxVal - minVal < 5;
        }
    }
    
    0 赞同 0 条回复
  • 訁訁訁訁訁 普通 2022年11月14日 下午10:02
    /**
    题目意思是 0 可以当替代牌,如
    0 0 1 3 5 -》 1 2 3 4 5 ,当我们的间隔数目大于0的数目时,显然
     */
    class Solution {
        public boolean isStraight(int[] nums) {
            Arrays.sort(nums);
            int zeroCnt = 0,diff = 0;
            for(int i = 0;i < nums.length - 1;i++){
                if(nums[i] == 0) {
                    zeroCnt++;
                }else{
                    //两张牌相同不用比较,一定不连续
                    if(nums[i] == nums[i + 1]) return false;
                    if(nums[i] + 1 != nums[i + 1]){//出现diff
                        diff += nums[i+1] - nums[i] - 1;
                    }
                }
            }
            return zeroCnt >= diff;
        }
    }
    
    0 赞同 0 条回复
  • 波波_1936 普通 2022年11月14日 下午9:31
     public boolean isStraight(int[] nums) {
            Arrays.sort(nums);
            //时间复杂度O(1)因为只有5个
            //空间复杂度O(1)
            //先排序 index就是大小王的个数 ,需要满足的条件是除了大小王,重复的值 最大的值-最小的值<5才能
            int index = 0;
            for (int i = 0; i < nums.length - 1; i++) {
                if (nums[i] == 0) {
                    index++;
                    //统计大小王的个数
                } else if (nums[i] == nums[i + 1]) {
                    //有重复
                    return false;
                }
            }
            return nums[nums.length - 1] - nums[index] < 5;
        }
    
    
    
    0 赞同 0 条回复
  • T 普通 2022年11月14日 下午8:36
    class Solution {
        public boolean isStraight(int[] nums) {
            Set<Integer> set = new HashSet<>();
            int max = 0, min = 14;
            for(int num : nums) {
                if(num == 0) continue;
                // 如果有重复直接退出
                if(set.contains(num)) return false;
                // 更新最大最小值
                max = Math.max(num, max);
                min = Math.min(num, min);
                set.add(num);
            }
            // 数学规律,如果 最大值-最小值 < 5则满足条件
            return max - min < 5;
        }
    }
    
    0 赞同 0 条回复

# 回答此问题

后才能回答