剑指offer第二版——面试题61(java)

面试题:扑克牌中的顺子

题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的

2~10位数字本身,A为1,J为11,Q为12,K为13,大小王可看成任意数字

思路:

可把5张牌看成5个数字组成的数组,大小王是特殊的数字(假设定义为0)

判断5个数字是不是连续的:把数组排序,由于0可以当成任意数字,因此可以用0去补满数组中的空缺——如果排序之后的数组不是连续的,但是有足够的0可以补满两个数字之间的空缺,则也可以说这个数组是连续的

并且,如果有两个非0数字相同,则不连续

步骤:

数组排序;统计0的个数;统计需要补的空缺总数;如果总数<0的个数,则连续,反之不连续

注意:

此处排序算法的时间复杂度为O(nlogn),还不够快,由于扑克牌的值只出现在0~13之间,因此可以定义一个长度为14的哈希表,可在O(n)时间内完成排序

但通常认为不同级别的时间复杂度只有当n足够大的时候才有意义,由于本题中的数组长度是固定的,只有5,因此上面两者不会有太大的区别

代码:

public class Q61 {
	public static void main(String[] args) {
		int[] a = new int[] {11,9,13,0,9};
		System.out.print(IsCont(a));
	}
	
	public static boolean IsCont(int[] a) {
		if(a==null || a.length==0) {
			return false;
		}
		// 排序
		Arrays.sort(a);
		
		// 0的个数和需要填补的数的个数
		int zero = zeroNum(a);
		int gap = gapNum(a,zero);
		
		// gap==-1表示有重复的数
		if(gap==-1) {
			return false;
		}
		// 根据两者的个数来判断
		if(gap<=zero) {
			return true;
		}else {
			return false;
		}
	}
	
	// 数组中0的个数
	public static int zeroNum(int[] a) {
		int m = 0;
		for(int i=0;i<a.length;i++) {
			if(a[i]==0) {
				m++;
			}else {
				return m;
			}
		}
		return m;
	}
	
	// 填补数的个数
	public static int gapNum(int[] a,int zero) {
		int sum = 0;
		for(int i=zero;i<a.length-1;i++) {
			if(a[i]==a[i+1]) {
				return -1;
			}
			if(a[i]+1!=a[i+1]) {
				sum = sum+a[i+1]-a[i]-1;
			}
		}
		return sum;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值