package com.dengzm.lib;
import java.util.Arrays;
/**
* @Description 061 扑克牌中的顺子
* 从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的
* 2-10为数字本身,A为1,JQK为11,12,13,大小王可以看成任意数字
*
* Created by deng on 2019/11/1.
*/
public class Jianzhi061 {
public static void main(String[] args) {
int[] data1 = new int[] {1,2,3,4,5};
int[] data2 = new int[] {1,2,3,3,5};
int[] data3 = new int[] {1,2,3,4,6};
int[] data4 = new int[] {0,2,3,4,5};
int[] data5 = new int[] {0,1,2,4,5};
System.out.println(isContinuous(data1));
System.out.println(isContinuous(data2));
System.out.println(isContinuous(data3));
System.out.println(isContinuous(data4));
System.out.println(isContinuous(data5));
}
/**
* 通过计算数组中空隙的数量与0的数量,比较大小
*
* @param numbers pokers
* @return is continuous
*/
private static boolean isContinuous(int[] numbers) {
if (numbers == null || numbers.length == 0) {
return false;
}
// 将数组排序
Arrays.sort(numbers);
int numberOfZero = 0;
int numberOfGap = 0;
// 统计出0的数量,同时也是非零数字开始的下标
for (int i = 0; i < numbers.length && numbers[i] == 0; i ++) {
numberOfZero ++;
}
int small = numberOfZero;
int big = small + 1;
while (big < numbers.length) {
// 有相同的牌时,为对子,不是顺子
if (numbers[small] == numbers[big]) {
return false;
}
numberOfGap += numbers[big] - numbers[small] - 1;
small = big ++;
}
return numberOfGap <= numberOfZero;
}
}
package com.dengzm.lib;
import java.util.LinkedList;
/**
* @Description 062 圆圈中最后剩下的数字
* 0~n-1,共n个数字,排成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字,求出这个圆圈里剩下的最后一个数字
*
* Created by deng on 2019/11/1.
*/
public class Jianzhi062 {
public static void main(String[] args) {
System.out.println(lastRemaining(5, 3));
System.out.println(lastRemaining(15, 13));
System.out.println(lastRemaining2(5, 3));
System.out.println(lastRemaining2(15, 13));
}
/**
* 解法一:环形链表模拟圆圈
*
* @param n num
* @param m delete position
* @return last remaining number
*/
private static int lastRemaining(int n, int m) {
if (n < 1 || m < 1) {
return -1;
}
// 圆圈——双向链表
// 这里参考了网上的方式,并不需要使用循环链表,只需要计算出需要删除的节点下标即可
LinkedList<Integer> queue = new LinkedList<>();
for (int i = 0; i < n; i ++) {
queue.addLast(i);
}
// 上一次删除的位置
int removeIndex = 0;
while (queue.size() > 1) {
removeIndex = (removeIndex + m - 1) % queue.size();
queue.remove(removeIndex);
}
return queue.getFirst();
}
/**
* 解法二:数学公式
* 首先,定义一个关于n和m的方程f(n,m),表示每次在n个数字0~n-1中删除第m个数字最后剩下的数字
* 在n个数字中,第一个被删除的数字是(m-1)%n,记为k,则第二次删除开始时,从k+1开始,序列为k+1, ..., n-1, 0, 1,..., k-1
* 将该序列与0~n-2进行映射可得到映射函数p(x)=(x-k-1)%n。该函数的逆映射为p-1(x)=(x+k+1)%n
* 映射后的序列与最初的序列类似,记为f(n-1,m)。将删除第一个数字后的函数代入,
* 得到f(n,m)=f'(n-1,m)=p-1[f(n-1,m)]=[f(n-1,m)+k+1]%n,把k=(m-1)%n代入得到,f(n,m)=[f(n-1,m)+m]%n
*
* 经过上面的分析,得到了递归公式:
* f(n,m) = 0 (n = 1)
* = [f(n-1,m) + m] % n (n > 1)
*
* @param n num
* @param m delete position
* @return last remaining number
*/
private static int lastRemaining2(int n, int m) {
if (n < 1 || m < 1) {
return -1;
}
int last = 0;
for (int i = 2; i <= n; i ++) {
last = (last + m) % i;
}
return last;
}
}
package com.dengzm.lib;import java.text.NumberFormat;/** * @Description 060 n个骰子的点数 * 把n个骰子扔在地上,所有骰子朝上的一面的点数之和为s。输入n,打印出所有可能出现的值出现的概率 * * Created by deng on 2019/11/1. */public class Jianzhi...