【2019春招准备:9.算法进阶】
【内容】 topK DP red-black-tree trie字典树 【补充】
- topK
!如果 k 很小,例如10以内的话,则利用冒泡堆排都可以,毕竟 k 和 logk 相差不大,但是冒泡相对简单。 !如果 k 比较大,则不适合用冒泡,考虑堆排和快排,一个是nlogk,一个是 2n - (2n/2^logn),一般而言是快排比较快,但是如果数组会动态变化的话,堆排比较好,因为插入复杂度可以控制在logk,而快排是k。
求K个最大值用小顶堆,求K个最小值用大顶堆
package q3_sort;
import java.util.Arrays;
/**
* 新建一个小顶堆 初始化放入前K个 遍历后面N-K个 如果大于堆顶 将堆顶
*
* @author ziboris
* @date 2018年11月26日 下午4:48:21
*
*/
public class Test3_topK_heap {
static final int n = 3;// top的个数
static final int m = 20;// 数据集的原始个数
static final int a[] = new int[m];
static int topK[] = new int[n + 1];
public static void downAdjust(int low, int high) {
int i = low;
int j = i * 2;
while (j <= high) {
if (j + 1 <= high && topK[i] > topK[j + 1])
j = j + 1;
if (topK[i] > topK[j]) {
int temp = topK[i];
topK[i] = topK[j];
topK[j] = temp;
i = j;
j = j * 2;
} else {
break;
}
}
}
public static void get_topk() {
// init初始化小顶堆
for (int i = n / 2; i >= 1; --i) {
downAdjust(i, n);
}
for (int i = n; i < a.length - 1; ++i) {
if (a[i] > topK[1]) {
topK[1] = a[i];
for (int j = n / 2; j >= 1; --j) {
downAdjust(j, n);
}
}
}
}
public static void main(String[] args) {
for (int i = 0; i < m; ++i) {
a[i] = (int) (Math.random() * 100);
}
for (int i = 1; i <= n; ++i) {
topK[i] = a[i - 1];
}
System.out.println("original:" + Arrays.toString(a));
get_topk();
System.out.println("topK:" + Arrays.toString(topK));
}
}
快排
public static int Partition(int low, int high) {
int i = low, j = high, x = a[low];
if (low < high) {
while (i < j) {
while (i < j && a[j] >= x)
--j;
if (i < j)
a[i++] = a[j];
while (i < j && a[i] < x)
++i;
if (i < j)
a[j--] = a[i];
}
a[i] = x;
}
return i;
};
public static int get_topk(int start, int end, int k) {
int index = 0;
if (start < end) {
index = Partition(start, end);
if (index == k) {
for (int i = 0; i < k; ++i) {
topK[i] = a[i + 1];
}
} else if (index < k) {
index = get_topk(index + 1, end, k - index);
} else {
index = get_topk(start, index - 1, k);
}
}
return index;
}
上一篇:
Java基础知识总结(2021版)
