搜尋原題在這
題目描述:
有兩個大小為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 ...