演算法題目打卡 Ques20201007

2021-10-24 12:58:22 字數 2836 閱讀 9279

特別簡單的問題,從一組陣列中選出第k大的元素a[i],最容易想到的辦法時間複雜度為o(n^2),考慮快排中的劃分法(分治思想)

選擇的基準元素預設是陣列的第乙個。

對應**:

// 試用劃分法

int partselect(vector& a, int n, int k)

} }// 但是這樣每次分治迭代只會減少1的複雜度,最壞複雜度(n2)

其他劃分法主要過程如下圖所示:

圖1 《演算法導論 》p123

改進後的選擇問題的劃分法:改變劃分元素,使每次劃分規模減半,將a劃分為r(如r=5)個一組,共有n/5(向上取整)個組(取n/5個中位),每組找乙個中位數,把它們放到集合m中,可使用排序法。

talk is cheap,show me the code.

**的一些解釋,選用的排序演算法是改進後的插入排序(使用二分查詢去插),複雜度是o(nlogn),但是排序的元素是各個組的,總複雜度就是另外一回事來了。也可使用歸併排序,在下面的**中都有實現。

目錄3的演算法描述中選取各組中位數組成乙個新的組,看起來很簡單,但是下面實現的**中沒有增加新的陣列,都在乙個陣列中進行。具體表現為將選取的中位數通通聚集到陣列的前面。再排序,選出最終的,通過交換元素位置實現。

在除錯時,發現最開始是3組,遞迴到最後是1組,所以加了一些判斷,**看起來有點複雜和亂,暫時不管了~能力有限見諒,有錯誤敬請指正~

//選擇問題

//問題描述:在乙個陣列a[1..n]中尋找第k小元素t,並將其存放於位置k,即a[k]=t。

#include using namespace std;

#include#include class selectpartitionclass

while (left& a, int n, int k)

} }// 但是這樣每次分治迭代只會減少1的複雜度,最壞複雜度(n2)

int midposition = 0;

// 改進後的選擇問題的劃分法:改變劃分元素,使每次劃分規模減半

int select(vector&arr,int m,int p,int k)

while(true)

}else

else

}int newright = m + floor(n / r) ;// 分成了3組就有3個中位數[0,2]再次進行排序,選最終的中位數

// 為什麼要將ceil(floor(n/r)/2 中值的中值 作為k傳入=>選好的中位數現在排在最前面,還需要再中位數中選出中位數

j=select(arr,m, newright,ceil(floor(n/r)/2));// 左邊界m,右邊界m+floor(n/r)-1,中值的中值

// 這裡期望j返回的是什麼呢?返回中位數的位置?

swap(arr[m],arr[j]);

}midposition= partition(arr,m, p); // 以最終選出的中位數arr[m],這裡中位數已經被收集到前面了作為參照數,將陣列s劃分為兩個部分,使得m所處的位置比左側的數目大1

if (midposition-m+1==k) else if(midposition -m+1>k) else }}

private:

// 二分法 查詢插入位置

int searchinsert(vector& array, int left, int right, int target)

*/while (left <= right)

else if (array[mid] < target)//如果中間值偏小,將初端右移

else //中間值偏大則終端左移

}return left;//如果目標值target比最大值還大,最後left>right,left=nums.size()

//如果比最小值還小,最後left值為0,因為right會先減為-1後與left交換,left=0且比right大,跳出迴圈且符合題意,目標值變為初端

}// 插入排序,時間複雜度是n^2,但是使用二分查詢優化後的插入排序複雜度是o(nlogn)

void insertsort(vector& arr, int start, int end)

arr[k] = key;}}

}/*歸併排序的複雜度直接是o(nlogn)*/

void merge(vector& arr, int low, int mid, int high)

else

i++;

}if (h > mid)

}else

}for (int k = low; k <= high; k++)

}void mergesort(vector& arr, int low, int high)

}};//ques20200925

int main() ;

int a=cla.select(arrs, 0,12,6);

cout << a;

return 0;

}

-3,2,5,8,4,3,9,10,6,7,1,0,14
-3,0,1,2,3,4,5,6,7,8,9,10,14

第6大的元素是4.

測試了下,好像沒太多問題...希望= =

演算法題目打卡 Ques20201012

活動安排問題,乙個場地,安排盡量多的活動。活動安排 include include include using namespace std struct activity class ques20201012 void test vector activities private vectorgre...

演算法題目打卡 Ques20201017

設有n個顧客同時等待同一服務,顧客i需要的服務時間為t,1 i n,應如何安排n個顧客的服務次序才能使總的等待時間達到最小?總的等待時間是各顧客等待服務的總和。試給出你的做法的理由。使用貪心策略,將服務所需時間按從小到大進行排列,優先安排服務時間短的。二元字首碼 表示乙個字元的0,1字串不能是表示另...

演算法打卡Week2

例1 輸入 l1 2 4,3 l2 5 6,4 輸出 7,0,8 解釋 342 465 807 例2 輸入 l1 0 l2 0 輸出 0 學習鍊錶結構 鍊錶是一種遞迴的資料結構,由乙個個結點 node 組成,且每個節點都有資料域 value 和指標域 next head 為單鏈表的頭指標,永遠指向第...