【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版)