/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.*;
/* Name of the class has to be "Main" only if the class is public. */
class Solution {
class State {
int i; // index of x[]
int j; // index of y[]
int sum; // x[i] + y[j]
public State(int i, int j, int sum) {
this.i = i;
this.j = j;
this.sum = sum;
}
}
public int findKthDistinctSum(int[] x, int[] y, int k) {
if (x.length == 0 || y.length == 0) {
}
// use a min heap to poll the next state that has minimum sum
PriorityQueue<State> heap = new PriorityQueue<>(new Comparator<State>() {
public int compare(State a, State b) {
return a.sum - b.sum;
}
});
// use a hash set to avoid duplicate sum
Set<Integer> set = new HashSet<>();
// step 1. create initial state
int sum = x[0] + y[0];
heap.offer(new State(0, 0, sum));
set.add(sum);
// step 2. generate new states based on current state
// until we get the kth smallest sum
while (k-- > 1) {
State s = heap.poll();
// new state 1: x[i], y[j + 1]
if (s.j < y.length - 1) {
sum = x[s.i] + y[s.j + 1];
if (!set.contains(sum)) {
heap.offer(new State(s.i, s.j + 1, sum));
set.add(sum);
}
}
// new state 2: x[i + 1], y[j]
if (s.i < x.length - 1) {
sum = x[s.i + 1] + y[s.j];
if (!set.contains(sum)) {
heap.offer(new State(s.i + 1, s.j, sum));
set.add(sum);
}
}
}
return heap.poll().sum;
}
}
class Ideone
{
{
int A[] = {1, 2, 4, 6};
int B[] = {2, 3, 6};
int k = 4;
Solution sol = new Solution();
System.
out.
println(sol.
findKthDistinctSum(A, B, k
)); System.
out.
println(sol.
findKthDistinctSum(B, A, k
)); }
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5Qcmlvcml0eVF1ZXVlOwppbXBvcnQgamF2YS51dGlsLio7CgovKiBOYW1lIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgIk1haW4iIG9ubHkgaWYgdGhlIGNsYXNzIGlzIHB1YmxpYy4gKi8KY2xhc3MgU29sdXRpb24gewoKICBjbGFzcyBTdGF0ZSB7CiAgICBpbnQgaTsgICAvLyBpbmRleCBvZiB4W10KICAgIGludCBqOyAgIC8vIGluZGV4IG9mIHlbXQogICAgaW50IHN1bTsgLy8geFtpXSArIHlbal0KCiAgICBwdWJsaWMgU3RhdGUoaW50IGksIGludCBqLCBpbnQgc3VtKSB7CiAgICAgIHRoaXMuaSA9IGk7CiAgICAgIHRoaXMuaiA9IGo7CiAgICAgIHRoaXMuc3VtID0gc3VtOwogICAgfQogIH0KCiAgcHVibGljIGludCBmaW5kS3RoRGlzdGluY3RTdW0oaW50W10geCwgaW50W10geSwgaW50IGspIHsKICAgIGlmICh4Lmxlbmd0aCA9PSAwIHx8IHkubGVuZ3RoID09IDApIHsKICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ2FuJ3QgaGFuZGxlIHplcm8tbGVuZ3RoIGFycmF5cy4iKTsKICAgIH0KCiAgICAvLyB1c2UgYSBtaW4gaGVhcCB0byBwb2xsIHRoZSBuZXh0IHN0YXRlIHRoYXQgaGFzIG1pbmltdW0gc3VtCiAgICBQcmlvcml0eVF1ZXVlPFN0YXRlPiBoZWFwID0gbmV3IFByaW9yaXR5UXVldWU8PihuZXcgQ29tcGFyYXRvcjxTdGF0ZT4oKSB7CiAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShTdGF0ZSBhLCBTdGF0ZSBiKSB7CiAgICAgICAgcmV0dXJuIGEuc3VtIC0gYi5zdW07CiAgICAgIH0KICAgIH0pOwoKICAgIC8vIHVzZSBhIGhhc2ggc2V0IHRvIGF2b2lkIGR1cGxpY2F0ZSBzdW0KICAgIFNldDxJbnRlZ2VyPiBzZXQgPSBuZXcgSGFzaFNldDw+KCk7CgogICAgLy8gc3RlcCAxLiBjcmVhdGUgaW5pdGlhbCBzdGF0ZQogICAgaW50IHN1bSA9IHhbMF0gKyB5WzBdOwogICAgaGVhcC5vZmZlcihuZXcgU3RhdGUoMCwgMCwgc3VtKSk7CiAgICBzZXQuYWRkKHN1bSk7CgogICAgLy8gc3RlcCAyLiBnZW5lcmF0ZSBuZXcgc3RhdGVzIGJhc2VkIG9uIGN1cnJlbnQgc3RhdGUKICAgIC8vIHVudGlsIHdlIGdldCB0aGUga3RoIHNtYWxsZXN0IHN1bQogICAgd2hpbGUgKGstLSA+IDEpIHsKICAgICAgU3RhdGUgcyA9IGhlYXAucG9sbCgpOwoKICAgICAgLy8gbmV3IHN0YXRlIDE6IHhbaV0sIHlbaiArIDFdCiAgICAgIGlmIChzLmogPCB5Lmxlbmd0aCAtIDEpIHsKICAgICAgICBzdW0gPSB4W3MuaV0gKyB5W3MuaiArIDFdOwoKICAgICAgICBpZiAoIXNldC5jb250YWlucyhzdW0pKSB7CiAgICAgICAgICBoZWFwLm9mZmVyKG5ldyBTdGF0ZShzLmksIHMuaiArIDEsIHN1bSkpOwogICAgICAgICAgc2V0LmFkZChzdW0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gbmV3IHN0YXRlIDI6IHhbaSArIDFdLCB5W2pdCiAgICAgIGlmIChzLmkgPCB4Lmxlbmd0aCAtIDEpIHsKICAgICAgICBzdW0gPSB4W3MuaSArIDFdICsgeVtzLmpdOwoKICAgICAgICBpZiAoIXNldC5jb250YWlucyhzdW0pKSB7CiAgICAgICAgICBoZWFwLm9mZmVyKG5ldyBTdGF0ZShzLmkgKyAxLCBzLmosIHN1bSkpOwogICAgICAgICAgc2V0LmFkZChzdW0pOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIHJldHVybiBoZWFwLnBvbGwoKS5zdW07CiAgfQoKfQpjbGFzcyBJZGVvbmUKewoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCgl7CgkJaW50ICBBW10gPSB7MSwgMiwgNCwgNn07CgkJaW50ICBCW10gPSB7MiwgMywgNn07CgkJaW50ICBrID0gNDsKCQlTb2x1dGlvbiBzb2wgPSBuZXcgU29sdXRpb24oKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oc29sLmZpbmRLdGhEaXN0aW5jdFN1bShBLCBCLCBrKSk7CgkJU3lzdGVtLm91dC5wcmludGxuKHNvbC5maW5kS3RoRGlzdGluY3RTdW0oQiwgQSwgaykpOwoJfQp9