1. 程式人生 > >C++演算法 求陣列中最小的K個數

C++演算法 求陣列中最小的K個數

輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4。

解法一:排序後,取出前k個數。O(nlogn)。

程式碼略。

解法二:建立n個元素的最小堆,每次去除堆頂的最小值,然後彈出堆頂,重新構成最小堆。

O(klogn)

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
    {
        vector<int> ret;
        if (input.empty() || k > input.size())
            return ret;
        make_heap(input.begin(), input.end(), greater<int>());
        for (int i = 0; i < k; i++)
        {
            pop_heap(input.begin(), input.end(), greater<int>());
            ret.push_back(input.back());
            input.pop_back();
        }
        return ret;
    }
};

解法三:建立k個元素的最大堆(藉助multiset來完成),遍歷陣列,

1、如果堆沒有k個元素 或者 當前陣列元素比堆頂小,那就把堆頂彈出,當前元素壓入,重新構成堆

2、否則,遍歷陣列下一個元素

最後堆中的元素就是最小的k個數。

O(nlogk) 適合海量資料

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
    {
        vector<int> ret;
        if (input.empty() || k > input.size())
            return ret;
        
        for (int i = 0; i < k; i++)
            ret.push_back(input[i]);
        make_heap(ret.begin(), ret.end(), less<int>());
        
        
        for (int i = k; i < input.size(); i++)
        {
            if (input[i] < ret[0])
            {
                pop_heap(ret.begin(), ret.end(), less<int>());
                ret.pop_back();
                ret.push_back(input[i]);
                push_heap(ret.begin(), ret.end(), less<int>());
            }
        }
        return ret;
    }
};

解法三:快排變種,每次遍歷將陣列分為兩邊。

O(n)

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
    {
        if (input.empty() || k > input.size())
            return input;
        
        int start = 0, end = input.size() - 1;
        while (start < end)
        {
            int index = Partition(input, start, end);
            if (index < k - 1)
                start = index + 1;
            else if (index > k - 1)
                end = index;
            else
                break;
        }
        return vector<int> (input.begin(), input.begin() + k);
    }
    
    int Partition(vector<int>& input, int start, int end)
    {
        if (start >= end) return start;
        int i = start, j = end;
        int pivot = input[(end - start) / 2 + start];
        while (i <= j)
        {
            while (i <= j && input[j] > pivot)
                j--;
            while (i <= j && input[i] < pivot)
                i++;
            if (i <= j)
                swap(input[i++], input[j--]);
        }
        return (j >= start)? j : start;
    }
};

相關推薦

C++演算法 陣列K個數

輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4。 解法一:排序後,取出前k個數。O(nlogn)。 程式碼略。 解法二:建立n個元素的最小堆,每次去除堆頂的最小值,然後彈出堆頂,重新構成最小

陣列k個數以及海量資料大堆、multiset解決方案

【題目】 輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。 【方案一】 主要有兩種方案。第一是利用我們熟知的 partition 演算法,它是快速排序的核心,相信每個人都會。它可以用來求取陣列的任

bfprt演算法----找出陣列k個數(Java)

 無序陣列中最小的k個數 對於一個無序陣列,陣列中元素為互不相同的整數,請返回其中最小的k個數。 給定一個整數陣列A及它的大小n,同時給定k,請返回其中最小的k個數。 測試樣例: [1,2,4,3],4,2 返回:[1,2] (1)利用堆,時間複雜度O(Nlog

c++陣列大值

用algorithm中的max_elementmin_element這兩個函式返回的是位置指標,*max_element可以獲得最大值1)普通陣列用法!#include <algorithm>int main(){    int a[5] = { 2, 3, 5,

無序陣列k個數

題目描述 對於一個無序陣列,陣列中元素為互不相同的整數,請返回其中最小的k個數,順序與原陣列中元素順序一致。 給定一個整數陣列A及它的大小n,同時給定k,請返回其中最小的k個數。 測試樣例: [1,2,4,3],4,2 返回:[1,2] 思想:首先建

關於查詢陣列k個元素的解答 updated

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

java陣列大值

通過遍歷陣列來求最大最小值 預設最大值是第一個元素 預設最小值也是第一個元素 這裡有兩種方式來求 一種是記下最大值和最小值 另一種方式是記下最大值最小值在陣列中的下標 輸出的時候再通過下標輸出最大最小

尋找陣列k個數(快排和堆排)

題目描述 輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。 思路1:利用快排的思想,尋找第k個位置上正確的數,k位置

無序陣列K個數

public int[] findKthNumbers(int[] A, int n, int k) { int[] B = new int[n]; System.arr

分治演算法陣列大值

分治演算法是指將一個複雜的問題分成兩個或者幾個相同的小問題,再把子問題分成更小的問題,一直這樣迴圈下去,直到最後可以簡單的求解。原問題的解是子問題解的合併。 此演算法是許多高效演算法的基礎。今天是一個簡單的用分治法求一維陣列最大值最小值的問題。 在這裡使用了二分法來劃分。程

找出陣列K 個數

給定一個長度為 n 的陣列,要求輸出陣列中最小的 K 個數(k<n)。 思路: 最簡單的思路是將陣列進行排序,由小到大排序,則陣列最前面的 K 個既我們要求的。 但是這樣的時間複雜度為 nlon

陣列大值、值、平均值

/** * 用程式碼實現求陣列的最大值、最小值、平均值 * @author  * */public class ArrayMaxMinPjTest {    public static void main(String[] args) {        int a[] = {

找出無序陣列k個數(top k問題)

給定一個無序的整型陣列arr,找到其中最小的k個數 該題是網際網路面試中十分高頻的一道題,如果用普通的排序

分治法陣列大元素

原創 在陣列A[n]中,設m是其中最大元素,則m=max(A[0],max( A[1]……A[n-1]); 同理 max( A[1]……A[n-1] ) = max ( A[1] , max( A[2]……A[n-1] ); 設函式findMax( int index ) 是尋找陣列中最大

初學Java:計算陣列大值 ---計算陣列值----計算陣列之和----實現兩個陣列----拼接陣列擷取

public class ArrayUtils{ //建立類(陣列工具類) //1.計算陣列中最大值 public static int arrayMaxElement(int [] data){ //建立方法 if(data == null){

java陣列大值

java中陣列中求最大值 public class Max { public static void main(String[] args) { double[] myList = {1.9, 2.9, 3.4, 3.5,10,11,15,100,-1,-4.5

C++ 演算法陣列只出現一次的數字

題目: 一個整型數組裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度為O(n),控制元件複雜度為O(1) 演算法思路: 如果一個數組當中,只要一個數字出現一次,其他都是出現兩次,那麼我們只要把所有的數進行異或得到的就是結果 現在

分治練手之陣列大元素

程式碼: #include<stdio.h> int Max_Element(int *a,int s,int e){ int mid=(s+e)/2; int max,m1,m2;

找出旋轉陣列的元素

題目:把一個數組最開始的若干個元素移到陣列的末尾,我們稱之為陣列的旋轉。輸入一個遞增陣列的一個旋轉陣列,輸出旋轉陣列的最小元素,例如{3,4,5,1,2}為{1,2,3,4,5}的旋轉 分析:1.最簡單的做法就是遍歷該陣列的所有元素,比較每個元素的大小,選出最小的元素。具體

動態規劃法--陣列大子集合的和

例題:給定一個數組int[] a = {-9,1,3,5,-1,7,-5,3,1}; 計算陣列中連續的最大和以及出現的位置  輸出:下標1到5位連續的最大和為15 首先看到這種題目,我的第一反應·就是用氣泡排序的思想去做: public class zuoye{