Skip to content

Instantly share code, notes, and snippets.

@jtribble
Created January 20, 2016 17:07
Show Gist options
  • Save jtribble/3e3e4e3893d1289cb41c to your computer and use it in GitHub Desktop.
Save jtribble/3e3e4e3893d1289cb41c to your computer and use it in GitHub Desktop.
//
// See: http://careercup.com/question?id=16759664
//
// You have k lists of sorted integers. Find the smallest range
// that includes at least one number from each of the k lists.
//
// Input: [[4, 10, 15, 24, 26], [0, 9, 12, 20], [5, 18, 22, 30]]
// Output: [20, 24]
//
const smallestRange = initLists => {
let k = initLists.length;
// merge the lists into a single sorted list
// create data structure with origin & val
let sortedList = initLists.reduce((acc, curr, i, arr) => {
return mergeLists(acc, curr.map(val => {
return {
origin: i,
val
};
}));
}, []);
// find smallest range with unique origins
let result = [];
sortedList.reduce((acc, curr, i, arr) => {
// if any of the current range items are of the same
// origin, slice the array at i + 1
for (let i = 0; i < acc.length; i++) {
if (curr.origin === acc[i].origin) {
acc = acc.slice(i + 1);
break;
}
}
acc.push(curr);
if (acc.length === k) {
// if this new valid range is less than the
// smallest range, then save it as the result
if (result.length === 0 || acc[k - 1].val - acc[0].val < result[1] - result[0]) {
result = [acc[0].val, acc[k - 1].val];
}
// remove the first element from the accumulated array (rotate)
acc.shift();
}
return acc;
}, []);
return result;
};
/**
* Given two sorted int arrays, return a single sorted array
*
* @param {array} a - The first list
* @param {array} b - The second list
*/
const mergeLists = (a, b) => {
let result = [];
while (a.length > 0 && b.length > 0) {
result.push(a[0].val <= b[0].val ? a.shift() : b.shift());
}
while (a.length > 0) result.push(a.shift());
while (b.length > 0) result.push(b.shift());
return result;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment