题解 | #扑克牌顺子#【消耗存储数法】
扑克牌顺子
http://www.nowcoder.com/practice/762836f4d43d43ca9deb273b3de8e1f4
我打算将我的这种方法命名为:
消耗存储数法
我们拿到 5 张牌的数组后,若想检验是否为顺子,那么按正常的思维来说,我们就应该先让这组牌号序列往有序的方向先靠拢,也就是先进行排序,我这里使用的是冒泡排序(较少量数据的序列的排序,冒泡排序还是可以用一下的),之后大小王的数量,便对应着这个有序序列的前 m 个 0 ,其中 m 的范围是 4 >= m >= 0,因为题目中说了有两副牌,之后我们判断次序列是否为顺子,则可从第 m 个序列开始,因为前面都为大小王,可替代任意排,我们要优先考虑后面的,并通过已有的大小王,也就是 0 ,来弥补后续不能构成连续序列的情况,如果序列中两个数相差 2 ,则可消耗掉 1 个 0 来弥补,如果序列中两个数相等,则不能构成顺子,直接终止并返回 false 即可,因为总共数组中就 5 个数,如果序列中两个数相差数大于2,但此差 - 1 是小于等于 0 的当前剩余个数的,那么可以用 0 进行弥补,反之,则不能构成顺子,如果序列中两个数正好相差 1 ,那么本身两数已是连续数,可进行下一轮循环,如果最终循环结束,仍未退出函数,说明为此情况在循环中已经过充分检验,不满足任何一个不能构成顺子的条件,则返回 true 即可。
实现
public class JZ45扑克牌顺子 { public static boolean IsContinuous(int[] numbers) { bubbleSort(numbers); int len = numbers.length; int zeroNum = 0; //求出大小王的个数,即 0 的个数 for (int i = 0; i < len; i++) { if (numbers[i] == 0) { zeroNum++; } } //判断顺子,从第 1 个不是 0 的数开始判断 i 与 i+1 的差值 boolean result = false; for (int i = zeroNum; i < len - 1; i++) { if (numbers[i + 1] - numbers[i] == 2) { //情况:两个数直接缺一个数导致不连续 if (zeroNum == 0) { //不可以弥补这种情况 return false; } //消耗掉一个大小王来弥补这种情况的不连续,使之连续 zeroNum--; } else if (numbers[i + 1] - numbers[i] == 1) { //情况:正好连续 } else { //情况:出现两个相邻数相等或大于2的情况 if (numbers[i + 1] == numbers[i]) { //情况:出现两个相邻数相等 return false; } //情况:如果有两张及以上的0(因为题中说了是两副牌),可以弥补大于2的部分情况 //相差2,需要1张0 ----> 相差n,需要n-1张0 else if (zeroNum >= numbers[i + 1] - numbers[i] - 1) { zeroNum -= (numbers[i + 1] - numbers[i] - 1); } else { //情况:大于2中不能弥补的情况 return false; } } } return true; } public static void bubbleSort(int[] numbers) { int i = 0; int j = 0; int len = numbers.length - 1; boolean flag = true; for (i = 0; i < len && flag; i++) { flag = false; for (j = len - 1; j >= i; j--) { if (numbers[j] > numbers[j + 1]) { swap(numbers, j, j + 1); flag = true; } } } } public static void swap(int[] numbers, int x, int y) { int m = numbers[x]; numbers[x] = numbers[y]; numbers[y] = m; } public static void main(String[] args) { int[] arr1 = {6, 0, 2, 0, 4}; int[] arr2 = {0, 3, 2, 6, 4}; int[] arr3 = {1, 0, 0, 1, 0}; int[] arr4 = {13, 12, 11, 0, 1}; System.out.println("IsContinuous(arr1) = " + IsContinuous(arr1)); //T System.out.println("IsContinuous(arr2) = " + IsContinuous(arr2)); //T System.out.println("IsContinuous(arr3) = " + IsContinuous(arr3)); //F System.out.println("IsContinuous(arr4) = " + IsContinuous(arr4)); //F } }