acwing-786. 第k個數
阿新 • • 發佈:2022-01-16
給定一個長度為 n 的整數數列,以及一個整數 k,請用快速選擇演算法求出數列從小到大排序後的第 k 個數。
輸入格式
第一行包含兩個整數 n 和 k。
第二行包含 n 個整數(所有整數均在 1∼10^9 範圍內),表示整數數列。
輸出格式
輸出一個整數,表示數列的第 k 小數。
資料範圍
1≤n≤100000,
1≤k≤n
輸入樣例:
5 3
2 4 1 5 3
輸出樣例:
3
方法一:
藉助快排中partition的思想,假設第一個數是要找的第k小的數,對待處理資料一輪partition過後,若這個數所在的位置處於陣列的
- 第k個位置,輸出該數,演算法完成
- 若所在位置<k,則對該元素為pivot的右邊部分的元素進行partition
- 若所在位置>k,則以該元素為pivot的左邊部分的元素進行partition
若隨機取pivot,平均時間複雜度為O(n)
這裡程式碼懶得隨機取了,AC
#include <bits/stdc++.h> int nums[1000010]; int findMid(int low, int high, int k) { int pivot = nums[low], l = low, h = high; while (low < high) { while (low < high && nums[high] >= pivot) high--; nums[low] = nums[high]; while (low < high && nums[low] <= pivot) low++; nums[high] = nums[low]; } if (low == k) return pivot; else if (low < k) return findMid(low + 1, h, k); else return findMid(l, low-1, k); } int main() { int n, k, a, b; scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) { scanf("%d", &(nums[i])); } printf("%d", findMid(1, n, k)); }