數組中第K大的元素

數組中第K大的元素總結java

        

解法1 咱們能夠對這個亂序數組按照從大到小先行排序,而後取出前k大,總的時間複雜度爲O(n*logn + k)數組

解法2 若是k很小,好比第五個最大的數,而整個數組的長度很是的大,那麼,還有一種方法就是,我作k遍找最大的數,每作一遍,就把最大的放在數組的最後面(遍歷一次找出最大的數例如冒泡,選擇排序均可以。),而後減小數組掃描的範圍,就能夠把第k大的數找出來,這樣作的複雜度就是O(K*N),在K很小的狀況下,仍是不錯的。測試

解法3 利用快速排序的思想,從數組S中隨機找出一個元素X,把數組分爲兩部分SaSbSa中的元素大於等於XSb中元素小於X。第K大的元素在已排序數組中的下標應爲index(第K大元素)=數組長度-1。記元素X的下標爲index(x),當index(x)= index(第K大元素),表示找到結果,返回。spa

       這時有兩種狀況:.net

           1. index(x)> index(第K大元素),則繼續在下標index(x)的左邊找code

           2. index(x)> index(第K大元素),則繼續在下標index(x)的右邊找htm

 解法4 二分[Smin,Smax]查找結果X,統計X在數組中出現,且整個數組中比X大的數目爲k-1的數即爲第k大數。時間複雜度平均狀況爲O(n*logn)blog

解法5:用O(4*n)的方法對原數組建最大堆,而後popk次便可。時間複雜度爲O(4*n + k*logn)排序

解法6:維護一個k大小的最小堆,對於數組中的每個元素判斷與堆頂的大小,若堆頂較大,則無論,不然,彈出堆頂,將當前值插入到堆中。時間複雜度O(n * logk)get

解法7利用計數排序的思想,,前面有k-1個數則爲第k大數,平均狀況下時間複雜度O(n)。

 像解法3和6應該是比較常見的解法:

    下面是解法3的java代碼

package com.wj;

/**
 * Created by wangjia .
 * Date:2015/9/5 0005
 * Time:10:53
 */
public class MaxK {
   public int getIndexK(int[] nums, int left, int right, int k) {
    int i = left, j = right;
    while (i < j) {
        while (nums[j] >= nums[left] && i < j) {
            j--;
        }
        //因此交換結束後,須要爲第一個基準元素找位置,這個位置就是如今i的位置.
        while (nums[i] < nums[left] && i < j) {
            i++;
        }
        if (i < j) {
            swap(nums, i, j);
        }
    }
    swap(nums, left, i);
    if (k == i) {
        return nums[i];
    } else if (k < i) {
        return getIndexK(nums, left, i - 1, k);
    } else {
        return getIndexK(nums, i + 1, right, k);
    }
}
//交換數組兩個數的位置
private void swap(int[] nums, int i, int j) {
    int tmp = nums[i];
    nums[i] = nums[j];
    nums[j] = tmp;
}

public int getK(int[] arr, int k) {
    return getIndexK(arr, 0, arr.length - 1, arr.length - k);
}
}
//時間複雜度:接近O(N)

測試代碼:

package com;

import com.wj.MaxK;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/** 
 * MaxK Tester. 
 * Created by wangjia .
 * Date:09/05/2015
 * Time:$Time
 *
*/ 
public class MaxKTest { 
    private MaxK instance;
    @Before
    public void before() throws Exception { 
        instance=new MaxK();
    }
    @After
    public void after() throws Exception { 
        instance=null;
    }
    @Test
    public void testGetK() throws Exception { 
        int[] arr={4, 5, -1, 2, 3};
        Assert.assertEquals(-1,instance.getK(arr, 5));
        Assert.assertEquals(5,instance.getK(arr, 1));
        Assert.assertEquals(4,instance.getK(arr, 2));
        Assert.assertEquals(3,instance.getK(arr, 3));
        Assert.assertEquals(2,instance.getK(arr, 4));
        int[] arr2={-8,11,4,-2,44,56565,23,-232};

        Assert.assertEquals(56565,instance.getK(arr2, 1));
        Assert.assertEquals(44,instance.getK(arr2, 2));
        Assert.assertEquals(-232,instance.getK(arr2, 8));
    }
}

解法6下次再來。

另外給出一些其餘的參考文章:http://blog.csdn.net/beiyeqingteng/article/details/6992290

http://job.xdnice.com/content/BiShiJingYan/2012-11/3971.htm

相關文章
相關標籤/搜索