兩個有序陣列間相加和的topk問題
給定兩個有序陣列arr1和arr2,再給定乙個整數k,返回來自arr1和arr2的兩個數相加和最大的前k個,兩個數必須分別來自兩個陣列
按照降序輸出
[要求]
時間複雜度為o(k
logk)
o(k \log k)
o(klogk)
輸入描述:
第一行三個整數n, k分別表示陣列arr1, arr2的大小,以及需要詢問的數
接下來一行n個整數,表示arr1內的元素
再接下來一行n個整數,表示arr2內的元素
輸出描述:
輸出k個整數表示答案
示例1輸入
5 4
1 2 3 4 5
3 5 7 9 11
輸出16 15 14 14
備註:
1 ⩽n
⩽105
1 \leqslant n \leqslant 10^5
1⩽n⩽1050⩽
arr1
i,ar
r2i⩽
10
90 \leqslant arr_}, arr_} \leqslant 10^9
0⩽arr1
i,
arr2
i⩽
109保證1⩽k
⩽2
n1 \leqslant k \leqslant 2n
1⩽k⩽2n
題解:一般涉及到topk
問題,首先應該想到使用堆2333。
我們可以知道 a[n-1] + b[n-1] 是整體的最大值,那麼在這個最大值之後應該是哪個元素呢,應該是:max
max\
max,它倆就是下乙個可能最大值,絕不會出現比它們更大的元素。
我們可以使用乙個大根堆,每個節點儲存三個元素
\,且 a[i
dx1]
+b[i
dx2]
=sum
a[idx1]+b[idx2] = sum
a[idx1
]+b[
idx2
]=su
m,兩個下標用來表明該元素由兩個陣列中哪兩個元素湊成的。
選擇堆頂元素,其就是整體的最大值,將其刪除,然後把兩個可能的最大元素插入到堆中去:
這樣進行 k 次操作後,就可以得到整體的 topk 了。
注意:1. 需要判重,因為兩個節點的下標有可能相等
2. 測試資料出現無序的情況。。。。。。
**:
#
include
#include
#include
#include
using
namespace std;
const
int n =
100000
;typedef pair<
int,
int> pii;
typedef pair<
int, pii> pip;
int n, k;
int a[n]
, b[n]
;int
main
(void)}
);hash[
(n -1)
* n + n -1]
=true
;while
( k--)}
);hash[key]
=true;}
key =
(x -1)
* n + y;
if( x &&
!hash.
count
(key))}
);hash[key]
=true;}
}return0;
}
貼乙個正兒八經的 o(klogk) 複雜度**:#
include
#include
#include
#include
using
namespace std;
const
int n =
1e5+10;
int a[n]
;int b[n]
;using pii = pair<
int,
int>
;int
main
(void);
priority_queue
,decltype
(cmp)
>
heap
(cmp)
;int r =
max(
0, n - k)
;for
(int i = n -
1; i >= r ;
--i )
while
( k--
)return0;
}
其他題目 兩個有序陣列間相加和的TopK問題
題目 給定兩個有序陣列arr1和arr2,再給定乙個整數k,返回來自arr1和arr2的兩個數相加和最大的前k個,兩個數必須分別來自兩個陣列。要求時間複雜度o klogk 基本思路 使用大根堆結構。假設arr1的長度是m,arr2的長度是n。因為是排序陣列,arr1中最後乙個數加上arr2中最後乙個...
歸併兩個有序陣列
題目 有兩個有序的陣列a1和a2,內存在a1的末尾有足夠多的空餘空間容納a2。請實現乙個函式,把a2中的所有數字插入到a1中並且所有的數字是排序的。解法 從後向前依次比較處理,減少移動次數,提高效率。void sorta1a2 int a1,int length1,int sizeofa1,int ...
合併兩個有序陣列
例如 陣列a1 陣列a2 則合併為a3 思路 依次掃瞄a1和a2的元素 比較當前元素的值,將較小的元素賦給a3,直到乙個陣列掃瞄完畢,然後將另乙個陣列的剩餘元素賦給a3即可。陣列a3的容量需要容納a1和a2兩個陣列和長度和。實現 include include void merge int a1,i...