我们知道包含 N 个元素的堆可以看成是一棵包含 N 个节点的完全二叉树。
每个节点有一个权值。对于小根堆来说,父节点的权值一定小于其子节点的权值。
假设 N 个节点的权值分别是 1~N,你能求出一共有多少种不同的小根堆吗?
例如对于 N=4 有如下 3 种:
1 1 1
2 3 3 2 2 4
4 4 3
【输入格式】 一个整数 N。
对于 40% 的数据,1 <= N <= 1000
对于 70% 的数据,1 <= N <= 10000
对于 100% 的数据,1 <= N <= 100000
【输出格式】 一个整数表示答案。
代码
public class CountHeaps {
static int count = 1;
public static void main(String args[]) {
//常规代码
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
if(n<=1) { //判断,如果只有1个或2个元素,排列组合只有1种
System.out.println(1);
}else { //否则,回溯判断
fullSort(arr, 2, arr.length - 1);
System.out.println(count);
}
}
//全排列回溯代码
public static void fullSort(int[] arr, int start, int end) {
//套模板
if (start == end) {
if (check(arr)) {
count++;
}
return;
}
for (int i = start; i <= end; i++) {
swap(arr, i, start);
fullSort(arr, start + 1, end);
swap(arr, i, start);
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//判断条件:从n>=2开始,只要出现子结点大于父节点,就返回false
public static boolean check(int[] arr) {
for (int i = 2; i < arr.length; i++) {
if(arr[(i-1)/2]>=arr[i] || arr[(i-2)/2]>=arr[i]){
return false;
}
}
return true;
}
}
结果
考试锦鲤🐟🐟🐟