1. 程式人生 > 其它 >尋找第K個數的值

尋找第K個數的值

題目
以較高的效率求一組無序陣列中按從小到大排序後第K個數的值。
用上了我學會但不太熟的雙指標快速排序。
程式碼如下:

public static int selectK(int[] arr, int l, int r, int k) {
    int q = partition(arr, l, r);//
    int qk = q - l + 1;//元素在陣列中的位置
    if (qk == k)  return arr[q];
       else if (qk > k)  return selectK(arr, l, q - 1, k);//比目標位置大則在左邊區間找
       else  return selectK(arr, q + 1, r, k - qk);//比目標位置小則在右邊區間找
}
//快速排序
public static int partition(int[] arr, int l, int r) {
    int mid=l+(r-l>>1);
    mid=Utils.getMid(arr,l,mid,r);//我自己封裝的獲取三個數中為中位數的方法
    if (mid!=l){
        Utils.swap(arr,l,mid);//自己封裝的方法
    }
    int p = arr[l];
    int left = l + 1;
    int right = r;
    while (left <= right) {
        while (left <= right && arr[left] <= p) {
            left++;
        }
        while (left <= right && arr[right] > p) {
            right--;
        }
        if (left < right) {
            Utils.swap(arr, left, right);
        }
    }
    Utils.swap(arr, l, right);
    return right;
}

本題給我帶來的收穫是加深了我對雙指標快速排序的應用。
首先先將初始陣列第一次劃分partition(arr, 0, arr.length-1)。將arr[l],arr[mid],arr[r]中為中位數的值放到應該在的位置然後返回right。
因為對右指標的限定條件為left<=right&&arr[right]>p 所以right最後會停在左側陣列中最後一個比p小的位置,此位置即為本次p應該所在的位置。然後用q-l+1可以得出p在排序好之後所處位置。
測試程式碼:
在這裡插入圖片描述
結果如下:
在這裡插入圖片描述