1
////////////////////////////////////////////////////////////////////////////////////////////2
////////////////////////////////////////////////////////////////////////////////////////////3
////////////////////////////////////////////////////////////////////////////////////////////5
var minimumIncompatibility = function (nums, k) {7
if (nums.length === k) return 0;9
const maxInBucket = nums.length / k;11
for (const n of nums) {13
if (freqCount[n] === k) {22
/////// HERE is just saving time24
// create a cache (aka memo, dp, dynamic programming, momoization)26
// create a mask to know when all the indicies are used27
const allIndiciesUsedMask = 2 ** nums.length - 1;29
const dfs = (usedIndicesBitMask) => {30
// if we have used all the indicies then we return 031
if (usedIndicesBitMask === allIndiciesUsedMask) {34
// if we have seen this combination before, return the35
// result that was calculated before36
// otherwise do the hard work LOL37
if (cache[usedIndicesBitMask]) {38
return cache[usedIndicesBitMask];41
// find all the indicies that are available to be used42
// skip duplicate values43
const valsToIndices = {};44
for (let i = 0; i < nums.length; i++) {45
const indexMask = 1 << i;46
if (usedIndicesBitMask & indexMask) continue;47
const value = nums[i];48
if (!valsToIndices.hasOwnProperty(value)) {49
valsToIndices[value] = i;52
const indicesAvailable = Object.values(valsToIndices);54
// this is hard to explain but it's basically calculating the minimum55
// cost while marking the indicies that are going to be used for each57
let minIncompatibilityCost = Infinity;58
const combinations = createCombinations(indicesAvailable, maxInBucket);59
for (const indices of combinations) {60
let nextMask = usedIndicesBitMask;61
let minVal = Infinity;62
let maxVal = -Infinity;63
for (const index of indices) {64
minVal = Math.min(minVal, nums[index]);65
maxVal = Math.max(maxVal, nums[index]);66
nextMask = nextMask | (1 << index);68
const incompatibilityCost = maxVal - minVal;69
minIncompatibilityCost = Math.min(70
minIncompatibilityCost,71
dfs(nextMask) + incompatibilityCost74
return (cache[usedIndicesBitMask] = minIncompatibilityCost);79
function createCombinations(indices, len) {80
const combinations = [];82
if (indices.length < len) {86
const stack = [[[], 0]];87
while (stack.length > 0) {88
let [combi, i] = stack.pop();89
for (; i < indices.length; i++) {90
const combination = [...combi, indices[i]];91
if (combination.length === len) {92
combinations.push(combination);94
stack.push([combination, i + 1]);