zoukankan      html  css  js  c++  java
  • 最小的k个数 2.5

    基于partition做的,当index!=k时一直while循环

       

    如果index<k,在后面找

       

    如果index>k,在前面找

       

    另外最后的结果如果是0k-1k个数包括k-1的话,那么开始k-1传入数组

       

    如果不包括k-1的话,那么可以不用减1

       

    复杂度为NlogN

       

    另外有NlogK的算法,利用最小堆

       

    利用partition的解法

       

    package maxKNum_2_5;

       

    public class MinKNum_2_5 {

    static int minK(int[] a, int k) {

    k = k - 1;

    int index = partition(a, 0, a.length - 1);

    while (index != k) {

    if (index < k) {

    index = partition(a, index + 1, a.length - 1);

    } else {

    index = partition(a, 0, index - 1);

    }

    }

    return index;

    }

       

    static int partition(int[] a, int left, int right) {

    int i, j, t, key;

    key = a[left];

    i = left;

    j = right;

    while (i < j) {

    while (a[j] > key && i < j)

    j--;

    while (a[i] <= key && i < j)

    i++;

    if (i != j) {

    t = a[i];

    a[i] = a[j];

    a[j] = t;

    }

    }

    a[left] = a[i];

    a[i] = key;

    return i;

    }

       

    public static void main(String[] args) {

    // TODO Auto-generated method stub

    int[] a = { 5, 4, 2, 3, 1, 2, 4, 5, 6 };

    // System.out.println(partition(a, 0, a.length - 1));

    for (int i = 0; i < a.length; i++) {

    System.out.print(a[i]);

    }

    System.out.println();

    System.out.println(minK(a, 3));

    for (int i = 0; i < a.length; i++) {

    System.out.print(a[i]);

    }

    System.out.println();

    }

       

    }

       

    利用最小堆的解法

       

       

    public class MinHeap {

       

    private int[] data;

       

    public MinHeap(int[] data) {

    this.data = data;

    buildHeap();

    }

       

    // 完全二叉树只有数组下标小于或等于 (data.length) / 2 - 1 的元素有孩子结点,遍历这些结点。

    // *比如上面的图中,数组有10个元素, (data.length) / 2 - 1的值为4a[4]有孩子结点,但a[5]没有*

    private void buildHeap() {

    // TODO Auto-generated method stub

    for (int i = (data.length) / 2 - 1; i >= 0; i--) {

    heapify(i);

    }

    }

       

    private void heapify(int i) {

    // TODO Auto-generated method stub

    int left_index = left(i);

    int right_index = right(i);

    // 表示 根结点、左结点、右结点中最小的值的结点的下标

    int min_index = i;

    if (left_index < data.length && data[left_index] < data[min_index]) {

    min_index = left_index;

    }

    if (right_index < data.length && data[right_index] < data[min_index]) {

    min_index = right_index;

    }

    if (i == min_index) {

    return;

    }

    swap(i, min_index);

    heapify(min_index);

    }

       

    private void swap(int i, int min_index) {

    // TODO Auto-generated method stub

    int temp = data[i];

    data[i] = data[min_index];

    data[min_index] = temp;

    }

       

    private int right(int i) {

    // TODO Auto-generated method stub

    return 2 * i + 2;

    }

       

    private int left(int i) {

    // TODO Auto-generated method stub

    return 2 * i + 1;

    }

       

    // 获取堆中的最小的元素,根元素

    public int getRoot() {

    return data[0];

    }

       

    // 替换根元素,并重新heapify

    public void setRoot(int root) {

    data[0] = root;

    heapify(0);

    }

       

    public static void main(String[] args) {

    // TODO Auto-generated method stub

    int data[] = { 2, 3, 4, 5, 1 };

    MinHeap minHeap = new MinHeap(data);

    int root = minHeap.getRoot();

    System.out.println(root);

    for (int i = 0; i < data.length; i++) {

    System.out.println(data[i]);

    }

    }

       

    }

       

    public class TopK

    {

    public static void main(String[] args)

    {

    // 源数据

    int[] data = {56,275,12,6,45,478,41,1236,456,12,546,45};

       

    // 获取Top5

    int[] top5 = topK(data, 5);

       

    for(int i=0;i<5;i++)

    {

    System.out.println(top5[i]);

    }

    }

       

    // data数组中获取最大的k个数

    private static int[] topK(int[] data,int k)

    {

    // 先取K个元素放入一个数组topk

    int[] topk = new int[k];

    for(int i = 0;i< k;i++)

    {

    topk[i] = data[i];

    }

       

    // 转换成最小堆

    MinHeap heap = new MinHeap(topk);

       

    // k开始,遍历data

    for(int i= k;i<data.length;i++)

    {

    int root = heap.getRoot();

       

    // 当数据大于堆中最小的数(根节点)时,替换堆中的根节点,再转换成堆

    if(data[i] > root)

    {

    heap.setRoot(data[i]);

    }

    }

       

    return topk;

    }

    }

       

       

  • 相关阅读:
    去中心化存储的QoS是什么?
    谈如何真正地做好去中心存储?
    Kowala协议:一组分布式,自我调节,资产跟踪特性的加密货币(二)
    MySQL主从备份
    Java面试总结-基础篇2
    Java面试总结-基础篇1
    锁定网络问题的方法
    我是如何在实际项目中解决MySQL性能问题
    serialVersionUID的作用
    Windows和Linux下如何自动备份MySQL
  • 原文地址:https://www.cnblogs.com/keedor/p/4397661.html
Copyright © 2011-2022 走看看