第k小的數

2021-07-22 18:06:00 字數 1660 閱讀 1843

輸入n個整數和乙個正整數k(1<=k<=n),輸出這些整數從小到大排序後的第k個

思路1:最容易想到的方法:先對這個序列從小到大排序,然後輸出前面的最小的k個數即可。如果選擇快速排序法來進行排序,則時間複雜度:o(n*logn)

class solution  //時間複雜度o(nlogn)

};

思路2:在思路1的基礎上更進一步想想,題目並沒有要求要查詢的k個數,甚至後n-k個數是有序的,既然如此,咱們又何必對所有的n個數都進行排序列?如此,我們能想打的乙個方法是:遍歷n個數,先把最先遍歷到得k個數存入大小為k的陣列之中,對這k個數,利用選擇或交換排序,找到k個數中的最大數kmax(kmax設為k個元素的陣列中最大元素),用時o(k)(你應該知道,插入或選擇排序查詢操作需要o(k)的時間),後再繼續遍歷後n-k個數,x與kmax比較:如果x< kmax,則x代替kmax,並再次重新找出k個元素的陣列中最大元素kmax『;如果x>kmax,則不更新陣列。這樣,每次更新或不更新陣列的所用的時間為o(k)或o(0),整趟下來,總的時間複雜度平均下來為:n*o(k)=o(n*k)

class solution

int indexkth(int num,int k)//找到k個數中最大值的索引下標o(k)

}return index;

}};

思路3:與思路2方法類似,只是用容量為k的最大堆取代思路2中陣列的作用(從陣列中找最大數需要o(k)次查詢,而從更新乙個堆使之成為最大堆只需要o(logk)次操作)。具體做法如下:用容量為k的最大堆儲存最先遍歷到的k個數,並假設它們即是最小的k個數,建堆費時o(k)後,有k1< k2< …< kmax(kmax設為大頂堆中最大元素)。繼續遍歷數列,每次遍歷乙個元素x,與堆頂元素比較,x< kmax,更新堆(用時logk),否則不更新堆。這樣下來,總費時o(k+(n-k)*logk)=o(n*logk)。

class solution

}return num[0];

}void adjust(int a,int i,int n)//時間複雜度o(logn)

a[i]=temp;

}};

思路4:按程式設計之美中給出的描述,類似快速排序的劃分方法,n個數儲存在陣列s中,再從陣列中隨機選取乙個數x(隨機選取樞紐元,可做到線性期望時間o(n)的複雜度),把陣列劃分為sa和sb倆部分,sa<=x<=sb,如果要查詢的k個元素小於sa的元素個數,則返回sa中較小的k個元素,否則返回sa中所有元素+sb中小的k-|sa|個元素。像上述過程一樣,這個運用類似快速排序的partition的快速選擇select演算法尋找最小的k個元素,在最壞情況下亦能做到o(n)的複雜度。

class solution

int helper(int a,int low,int high,int k)

};

思路5:仍然用到資料結構:堆。具體做法為:針對整個陣列序列建最小堆,建堆所用時間為o(n),然後取堆中的前k個數,總的時間複雜度即為:o(n+k*logn)。

class solution

return num[length-k];

}void adjust(int a,int i,int n)//時間複雜度o(logn)

a[i]=temp;

}};

第k小的數

time limit 5000 ms memory limit 65536 kib problem description 現有乙個包含n個整數 1 n 10000000 的無序序列 保證序列內元素各不相同 輸入乙個整數k 1 k n 請用較快的方式找出該序列的第k小數並輸出。input 多組輸入。...

第k小的數

time limit 5000 ms memory limit 65536 kib submit statistic problem description 現有乙個包含n個整數 1 n 10000000 的無序序列 保證序列內元素各不相同 輸入乙個整數k 1 k n 請用較快的方式找出該序列的第k...

第k小的數

time limit 5000 ms memory limit 65536 kib submit statistic problem description 現有乙個包含n個整數 1 n 900000 的無序序列 保證序列內元素各不相同 輸入乙個整數k 1 k n 請用較快的方式找出該序列的第k小數...