剑指offer——扑克牌中的顺子

题目描述:

LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何。为了方便起见,你可以认为大小王是0。

解题思路:

  • 首先先对数字进行排序
  • 统计0的个数
  • 如果数字中相邻数字之间的空缺数小于等于0的个数,则可以凑成顺子
  • 一旦数字中出现了除0外重复的数字,则一定凑不成顺子

 public boolean isContinuous(int [] numbers) {
if(numbers.length<5||numbers==null)
    return false;
for(int x:numbers){
    if(x<0)//有负数,即为false
        return false;
}
int temp = 0;
//排序
for(int i = numbers.length-1;i>0;i--){
    for(int j = 0;j<i;j++){
        if(numbers[j]>numbers[j+1]){
            temp = numbers[j+1];
            numbers[j+1] = numbers[j];
            numbers[j] = temp;
        }
        else
            continue;
    }
}
int count_0 = 0;
int count = 0;
//统计大小王的个数
for(int i = 0;i<numbers.length;i++){
    if(numbers[i]==0)
        count_0++;
}
//不可能有5张大小王
if(count_0==5)
    return false;
if(count_0==4)
    return true;
boolean flag = true;
//一旦有两张重复,就不可能有顺子
for(int i=count_0;i<numbers.length-1;i++){
    if(numbers[i]==numbers[i+1]){
        flag = false;
        break;
    }
}
if(!flag)
    return false;
//求出相邻数字之间的空缺总数
for(int i = count_0;i<numbers.length-1;i++){
    count += numbers[i+1]-numbers[i]-1;
}
//大小王个数大于等于空缺总数时,能凑成顺子
if(count_0>=count)
    return true;
else
    return false;

}

对上述方法简化,利用Arrays.sort()来进行排序,但是一些特殊情况没有考虑,比如数字为负数的情况

public boolean isContinuous(int[] nums) {
if (nums.length < 5)
    return false;
Arrays.sort(nums);
int cnt = 0;
for (int num : nums)
    if (num == 0)
        cnt++;
for (int i = cnt; i < nums.length - 1; i++) {
    if (nums[i + 1] == nums[i])
        return false;
    cnt -= nums[i + 1] - nums[i] - 1;
}
return cnt >= 0;
}


猜你喜欢

转载自blog.csdn.net/caisongcheng_good/article/details/80699416