求兩個有序陣列兩兩相加的值最小的K個數

2021-06-29 14:06:50 字數 1256 閱讀 8110

搜尋原題在這

題目描述:

有兩個大小為n的有序陣列a、b(從大到小),現在需要找出k個最大的數字,其中每個數字是這樣構成的(ai+bj),0<=i,j

例1:input:

a為7 6 5 4 

b為4 3 2 1

k=4output:11 10 10 9

例2:

input:

a為7 4 3 2

b為6 3 1 1

k=6output:13 10 10 9 8 8

思路:

看到top k,會想到利用最大堆來降低複雜度。

思路一:暴力方法就是計算所有a[i]+b[j],然後排序找出top k。

思路二:其實所有的a[i]+b[j]構成一二維陣列,我們不妨將這個二維陣列寫出來如下:

-a[0]+b[0]>=a[0]+b[1]>=...>=a[0]+b[n-2]>=a[0]+b[n-1]

-a[1]+b[0]>=a[1]+b[1]>=...>=a[1]+b[n-2]>=a[1]+b[n-1]

-...

-a[n-1]+b[0]>=a[n-1]+b[1]>=...>=a[n-1]+b[n-2]>=a[n-1]+b[n-1]

看到這個二維陣列,立刻想到兩點:

思路一**:

空間o(m*n),這裡空間實際上可以不要。直接在二重迴圈下建堆入堆更新。

時間o(mnlog(mn)),這裡採用堆的話,時間o(mnlog(k))

vectorgettopkfromtwoarraysforce(int arr1, int m, int arr2, int n, int k)

思路二**(參考這裡):

空間:o(n)

struct node;

// 優先順序佇列的比較函式

struct cmp

};vectorgettopkfromtwoarrays(int arr1, int m, int arr2, int n, int k){

vectorres;

if(arr1==null || m<=0 || arr2==null || n<=0 || k<=0)

return res;

int *d = new int[m];

for(int i=0; i, cmp> q; //優先順序佇列

for(int i=0; i回顧

有序陣列兩兩交換,求最小的交換次數。

1 有序陣列,按照0到n 1的序列編號,順序打亂,請您用最小的交換操作次數,使其重新變成遞增序列。假如 編號儲存在乙個陣列array當中。一次交換操作可以將這個陣列的其中兩個數互換。限制 1 n 100000 例 1 輸入 array 2,0,1 輸出 2 解釋 先交換0和2 一次交換操作 再交換1...

求兩個有序陣列的中值

設陣列a的長度為m,陣列b的長度為n,兩個陣列都都是遞增有序的。求這兩個陣列的中值 如下 include int find median int a,int b,int m,int n,int s,int t b為空 if 0 n a p 太小了,從陣列a中找乙個更大的數嘗試 if c p 1 n ...

歸併兩個有序陣列

題目 有兩個有序的陣列a1和a2,內存在a1的末尾有足夠多的空餘空間容納a2。請實現乙個函式,把a2中的所有數字插入到a1中並且所有的數字是排序的。解法 從後向前依次比較處理,減少移動次數,提高效率。void sorta1a2 int a1,int length1,int sizeofa1,int ...