Skip to content

Instantly share code, notes, and snippets.

@joebutler2
Created February 20, 2021 19:58
Show Gist options
  • Save joebutler2/5315f2e7e074171fd861e5a50d965a69 to your computer and use it in GitHub Desktop.
Save joebutler2/5315f2e7e074171fd861e5a50d965a69 to your computer and use it in GitHub Desktop.
class Solution {
solve(points) {
const byX = {};
const byY = {};
const result = [];
// points.sort((a,b) => a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
for(let [x, y] of points) {
byX[x] = byX[x] || [];
byX[x].push(y);
byY[y] = byY[y] || [];
byY[y].push(x);
}
for(let key in byX) {
byX[key].sort((a,b) => a - b);
}
for(let key in byY) {
byY[key].sort((a,b) => a - b);
}
this.byX = byX;
this.byY = byY;
console.log(byX, byY)
for(let i = 0; i < points.length; i++) {
let [x, y] = points[i];
let dX = x;
let dY = y;
if(byX[x].length > 1 && byY[y].length == 1) {
// console.log("should be here")
// We don't want to match the same point.
dY = this.findClosestY(x, y)// (byX[x][0] == y) ? byX[x][1] : byX[x][0];
} else if(byX[x].length == 1 && byY[y].length > 1) {
dX = this.findClosestX(x, y)// (byY[y][0] == x) ? byY[y][1] : byY[y][0];
} else { // Then both points are valid.
let min = Number.MAX_SAFE_INTEGER;
// Try the point that matches on the X axis.
dY = this.findClosestY(x, y)//(byX[x][0] == y) ? byX[x][1] : byX[x][0];
min = Math.min(manhattanDistance(x, dX, y, dY), min);
// Now try the point that matches on the Y axis.
dY = y;
dX = this.findClosestX(x, y);//(byY[y][0] == x) ? byY[y][1] : byY[y][0];
min = Math.min(manhattanDistance(x, dX, y, dY), min);
result[i] = min;
continue;
}
// console.log(x,y, dX, dY)
result[i] = manhattanDistance(x, dX, y, dY);
}
return result;
}
findClosestX(x, y) {
let minValue = Number.MAX_SAFE_INTEGER;
let minDelta = Number.MAX_SAFE_INTEGER;
let index = binarySearch(this.byY[y], x);
for(let i = Math.max(index - 1, 0); i < Math.min(index + 1, this.byY[y].length); i++) {
if(i == index) continue;
let dX = this.byY[y][i];
let delta = Math.abs(x - dX);
if(delta < minDelta) {
minValue = dX;
minDelta = delta;
}
}
return minValue;
}
findClosestY(x, y) {
let minValue = Number.MAX_SAFE_INTEGER;
let minDelta = Number.MAX_SAFE_INTEGER;
let index = binarySearch(this.byX[x], y);
for(let i = Math.max(index - 1, 0); i < Math.min(index + 1, this.byX[x].length); i++) {
if(i == index) continue;
let dY = this.byX[x][i];
let delta = Math.abs(y - dY);
if(delta < minDelta) {
minValue = dY;
minDelta = delta;
}
}
return minValue;
}
}
const binarySearch = (target, arr) => {
return binarySearchRec(target, arr, 0, arr.length - 1);
}
const binarySearchRec = (target, arr, low, high) => {
if(low > high) return;
console.log("bs", target, low, high)
let mid = Math.floor(high - low / 2) + low;
if(arr[mid] == target) {
return mid;
} else if(arr[mid] < target) {
return binarySearchRec(target, arr, mid + 1, high);
} else {
return binarySearchRec(target, arr, low, mid - 1);
}
}
const manhattanDistance = (x, dX, y, dY) =>
Math.abs(x - dX) + Math.abs(y - dY);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment