剑指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的个数,表示有多少张大小王。还需要计算两个相邻数字之间的差的绝对值,因为,如果两个数之间的差太大的话,即使有很多张大小王也无济于事。有了这两个结果之后,就可以对牌进行判断了,不过在此之前需要对牌进行一个排序,这样统计起来更方便。还有一种情况是,如果牌中出现了对子,那么肯定不可能是顺子,所以综合以上分析,可以下出如下的实现代码(已被牛客AC):

package com.rhwayfun.offer;

import java.util.Arrays;

public class IsContinuousCard {

    public boolean isContinuous(int [] numbers) {
        if(numbers == null || numbers.length == 0) return false;

        //对数组进行排序
        Arrays.sort(numbers);

        //统计大小王的张数
        int numberOfZero = 0;
        int numberOfGap = 0;
        for(int i = 0; i < numbers.length && numbers[i] == 0; i++) numberOfZero++;

        int low = numberOfZero;
        int high = low + 1;
        while(high < numbers.length){
            //如果出现了对子则不可能是顺子
            if(numbers[low] == numbers[high]) return false;
            //计算空缺数
            numberOfGap += numbers[high] - numbers[low] - 1;
            low = high;
            high++;
        }

        return numberOfGap <= numberOfZero ? true : false;
    }

    public static void main(String[] args) {
        int[] numbers = {1,3,2,4,5};
        IsContinuousCard c = new IsContinuousCard();
        boolean f = c.isContinuous(numbers);
        System.out.println(f);
    }
}
时间: 2024-10-29 14:23:22

剑指offer系列之四十三:扑克牌顺子的相关文章

剑指offer系列之四十二:约瑟夫环问题

题目描述 每年六一儿童节,NowCoder都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为NowCoder的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指定一个数m,让编号为0的小朋友开始报数.每次喊到m的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0-m-1报数-.这样下去-.直到剩下最后一个小朋友,可以不用表演,并且拿到NowCoder名贵的"名侦探柯南"

剑指offer系列之四十八:把字符串转成整数

题目描述 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数 这里的关键是要对输入的字符串进行全面的考虑.包括字符串是否有效的判断.是否是负数以及字符串表示的整数是否越界等问题.对于字符串有效性的判断主要是null以及空串的判定:负数之所以需要判断是因为在计算的时候是有用的:而是否越界的问题也是需要考虑的.因为一个越界的数是不可能计算出来的,那么这时候可以简单返回一个0,表示越界的数.这三点都考虑之后,整体代码的健壮性就比较好了.下面是这种思路的实现代码(已被牛客AC),详细的已经在

剑指offer系列之四十六:求1到n的和

题目描述 求1+2+3+-+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 如果不能使用上面的操作,那么只能使用递归操作了.使用递归操作的思路是让函数不断调用自己,每调用一次值就减少1,这样完成了递归操作.还有一个问题是如何实现n范围的判断呢?注意到递归调用的n的值最小是1,所以可以通过逻辑与运算,判断是否递归到1.如果递归调用到1,那么递归就结束,并返回最后的结果.下面是这样思路的实现代码(已被牛客AC): packag

剑指offer系列之四十一:和为S的两个数字且乘积最小

题目描述 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输出描述: 对应每个测试案例,输出两个数,小的先输出. 有了上一题的基础,解决这题应该不难,思路与上一题差不多,不过这里只需要要求两个数字即可.所以可以设定两个指针,第一个指针指向数组的第一个元素,第二个指针指向最后一个元素,不断改变第一个指针的位置就可以确定和为S的两个数字.这里还有一个要求是这两个数字的乘积最小,实际上由于数组是递增排序的,所以第一个找到

剑指offer系列之四:重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 在完成代码之前,我自己分析了一下如何根据前序遍历和中序遍历的结果构建一棵二叉树.首先,根据二叉树遍历的性质,由前序遍历的结果序列可知该二叉树的根节点是1,在根据中序遍历的结果可是根节点1的左子树包含的结点是4.7.2,右子树包含的节点是5.3.8.6.

剑指offer系列之四十:和为S的连续正数序列

题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22.现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck! 输出描述: 输出所有和为S的连续正数序列.序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序 此题的思路是:设定两个指针,一个指向第一个

剑指offer系列之四十九:数组中重复的数字

题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3. 此题的思路还是比较简单的,与之前找出只出现一次的数字的题目有些类似,基本思路还是创建一个Map容器,key是出现的数字,value则是该数字出现的次数.在遍历数组的过程中,只要容器中已经出现了该数字,那么就直接返回给数组,

剑指offer系列之四十四:翻转单词顺序

题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,"student. a am I".后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是"I am a student.".Cat对一一的翻转这些单词顺序可不在行,你能帮助他么? 可以发现,要对一个句子进行翻转,可以先对整个句子进行翻转,之后再对每个单词进行翻转.而不论是返

剑指offer系列之五十三:字符流中第一个不重复的字符

题目描述 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g".当从该字符流中读出前六个字符"google"时,第一个只出现一次的字符是"l". 输出描述: 如果当前字符流没有存在出现一次的字符,返回#字符. 这题与前面的第一个不重复的字符有些重复了,所以直接看代码(已被牛客AC): package com.rhwayfun.offer; impor