28.剑指Offer之扑克牌顺子

1题目描述:

  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的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。

2.解题思路

  剑指offer题目描述越长,题目的难度反而一般比较小,因为越长的题目给出的要求更加具体,可用信息也越多。首先认真分析题意,我们可以得到以下几个信息:

  • 输入的是一个数组,并且长度为5,所有的元素都在0到13的范围内
  • 判断这5个元素能否构成顺子
  • 构成顺子的条件是:没有对子、最大最小值间隔不超过4,0可以充当任何数,相当于癞子

  首先将这个数组排序,由于0可以充当任何数,因此第二步需要统计0的个数,以确定有几个癞子,第三步需要统计排序数组中相邻数字之间的空缺总数。如果空缺总数小于等于0的个数,那么就说明可以构成顺子,反之则无法构成。

  另外,还需要注意两个限制:(1)如果非0数字重复出现,也就是有对子,那么无法构成顺子;(2)如果排序之后最大和最小值(0除外)之间的间隔超过4,那么无需进一步计算,可以直接返回false。该算法的时间复杂度主要取决于排序,因此一般情况下为O(nlogn)。

3.编程实现(Java):

public class isContinuous_28 {
    public boolean isContinuous(int[] numbers) {
        if (numbers == null || numbers.length < 5)
            return false;
        int len = numbers.length;
//        对数组进行排序
        Arrays.sort(numbers);

        int numOfZero = 0;
        for (int i = 0; i < len; i++) {
            if (numbers[i] != 0) {
                numOfZero = i;
                break;
            }
        }

        //最大值和最小值超过len-1就放回0
        if (numbers[len - 1] - numbers[numOfZero] > len - 1)
            return false;

        int count = 0;
        for (int i = numOfZero; i < len - 1; i++) {
            if (numbers[i] == numbers[i + 1])
                return false;
            count = count + (numbers[i + 1] - numbers[i] - 1);
        }

        if (count > numOfZero)
            return false;
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值