Back to all solutions
#2613 - Beautiful Pairs
Problem Description
You are given two 0-indexed integer arrays nums1 and nums2 of the same length. A pair of indices (i,j) is called beautiful if|nums1[i] - nums1[j]| + |nums2[i] - nums2[j]| is the smallest amongst all possible indices pairs where i < j.
Return the beautiful pair. In the case that there are multiple beautiful pairs, return the lexicographically smallest pair.
Note that
- |x| denotes the absolute value of x.
- A pair of indices (i1, j1) is lexicographically smaller than (i2, j2) if i1 < i2 or i1 == i2 and j1 < j2.
Solution
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var beautifulPair = function(nums1, nums2) {
const n = nums1.length;
const max = Math.max(...nums1, ...nums2);
const size = max + 1;
const indices = Array.from({ length: n }, (_, i) => i)
.sort((a, b) => nums1[a] === nums1[b] ? a - b : nums1[a] - nums1[b]);
nums1.push(-100000001);
nums2.push(100000000);
const tree1 = new Array(2 * size).fill(-1);
const tree2 = new Array(2 * size).fill(-1);
let best = null;
update(nums2[indices[0]], indices[0], 1);
update(nums2[indices[0]], indices[0], -1);
for (let i = 1; i < n; i++) {
const index = indices[i];
const y = nums2[index];
const left = query(0, y, -1);
const right = query(y, max, 1);
best = select(index, left, right);
update(y, index, -1);
update(y, index, 1);
}
return best;
function compare(i, j, dir) {
if (j === -1) return i;
if (i === -1) return j;
const vi = -nums1[i] + dir * nums2[i];
const vj = -nums1[j] + dir * nums2[j];
return vi < vj || (vi === vj && i < j) ? i : j;
}
function update(position, index, dir) {
position += size;
const tree = dir === 1 ? tree2 : tree1;
while (position > 0) {
const cur = tree[position];
const better = compare(index, cur, dir);
if (better !== index) return;
tree[position] = better;
position = Math.floor(position / 2);
}
}
function query(l, r, dir) {
l += size;
r += size;
const tree = dir === 1 ? tree2 : tree1;
let result = -1;
while (l <= r) {
if (l & 1) {
result = compare(result, tree[l], dir);
l++;
}
if (!(r & 1)) {
result = compare(result, tree[r], dir);
r--;
}
l = Math.floor(l / 2);
r = Math.floor(r / 2);
}
return result;
}
function select(x, y, z) {
const pairs = [];
if (y !== -1) {
const d = nums1[x] + nums2[x] - nums1[y] - nums2[y];
pairs.push([d, [Math.min(x, y), Math.max(x, y)]]);
}
if (z !== -1) {
const d = nums1[x] - nums2[x] - nums1[z] + nums2[z];
pairs.push([d, [Math.min(x, z), Math.max(x, z)]]);
}
if (best !== null) {
const d = Math.abs(
nums1[best[0]] - nums1[best[1]]) + Math.abs(nums2[best[0]] - nums2[best[1]]
);
pairs.push([d, best]);
} else {
pairs.push([Infinity, [-1, -1]]);
}
return pairs.sort((a, b) => {
if (a[0] !== b[0]) return a[0] - b[0];
if (a[1][0] !== b[1][0]) return a[1][0] - b[1][0];
return a[1][1] - b[1][1];
})[0][1];
}
};