题意整理

  • 现在有2副扑克牌,从扑克牌中随机五张扑克牌,判断这五张牌是不是顺子。
  • A为1,J为11,Q为12,K为13,A不能视为14,大小王为0,0可变成任意牌。

方法一(排序)

1.解题思路

  • 首先对数组进行排序。
  • 遍历整个数组,统计其中0的个数。再次遍历数组,统计其中待填补数字的个数,如果这个过程中,出现重复数字,直接返回false。
  • 最后计算0的个数以及待填补数字的个数的大小,如果前者大于等于后者,说明足够填充,直接返回true。否则,返回false。

2.代码实现

import java.util.Arrays;

public class Solution {
    public boolean IsContinuous(int [] numbers) {
        //特殊情况判断
        if(numbers==null||numbers.length==0){
            return false;
        }
        //排序
        Arrays.sort(numbers);
        //记录0的个数
        int numbersof0=0;
        //记录待填补数字的个数
        int numbersofspace=0;
        for(int i=0;i<numbers.length;i++) {
            if(numbers[i]==0) {
                numbersof0++;
            }
        }
        //从第二个非0的数开始遍历
        for(int i=numbersof0+1;i<numbers.length;i++) {
            if(numbers[i]==numbers[i-1]) {
                return false;
            }
            //计算待填补数字的个数
            numbersofspace+=numbers[i]-numbers[i-1]-1;
        }
        //如果足够填补,返回true
        if(numbersof0>=numbersofspace) {
            return true;
        }
        else {
            return false;
        }

    }
}

3.复杂度分析

  • 时间复杂度:需要遍历数组中所有元素,复杂度为O(n)O(n),同时需要对数组进行排序,时间复杂度为O(nlog2n)O(nlog_2n),所以时间复杂度为O(nlog2n)O(nlog_2n)
  • 空间复杂度:需要额外常数级别的空间,所以空间复杂度是O(1)O(1)

方法二(计数)

1.解题思路

  • 首先新建一个计数数组,用于统计所有牌出现的次数。
  • 遍历整个数组,如果为0,直接跳过。如果不为0,并且出现次数大于1,说明重复了,直接返回false。同时计算所有牌的最小值以及最大值。
  • 如果最大值与最小值之差小于5,直接返回true。否则,返回false。(简单证明:如果max、min之差小于5,除了最小值min和最大值max之外,另外三张牌要么是min、max之间,要么是0,总能填充成顺子。如果max、min之差大于等于5,则怎么也不能组成顺子,因为min作为最小值对应的顺子的最大值必定是min+4。而max>min+4,矛盾。)

图解展示: alt

2.代码实现

import java.util.Arrays;

public class Solution {
    public boolean IsContinuous(int [] numbers) {
        //特殊情况判断
        if(numbers==null||numbers.length==0){
            return false;
        }
        //统计每张牌出现的次数
        int[] d=new int[14];
        int max=-1;
        int min=14;
        for(int i=0;i<numbers.length;i++){
            d[numbers[i]]++;
            //为0则跳过
            if(numbers[i]==0){
                continue;
            }
            //如果出现次数大于1,说明重复了,直接返回false
            if(d[numbers[i]]>1)
                return false;
            //更新最大值
            if(numbers[i]>max){
                max=numbers[i];
            }
            //更新最小值
            if(numbers[i]<min){
                min=numbers[i];
            }
        }
        //如果最大值、最小值之间的差不超过5,则必定可组成顺子
        if(max-min<5){
            return true;
        }
        else{
            return false;
        }

    }
}

3.复杂度分析

  • 时间复杂度:需要遍历数组中所有的元素,所以时间复杂度为O(n)O(n)
  • 空间复杂度:需要额外大小为14的计数数组,为常数级别,所以空间复杂度是O(1)O(1)