Skip to content

Instantly share code, notes, and snippets.

@robertDurst
Created September 30, 2019 01:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertDurst/b58768f04b29f512286408aeb176fa80 to your computer and use it in GitHub Desktop.
Save robertDurst/b58768f04b29f512286408aeb176fa80 to your computer and use it in GitHub Desktop.
// started 8:00 - 8:45/9:00 (while chatting w/ friends)
const START_SIZE = 10;
const BUCKET_LIMIT = 3;
class HashMap {
constructor() {
this.values = new Array(START_SIZE);
this.count = START_SIZE;
this.length = START_SIZE;
}
hash(value) {
switch (typeof (value)) {
case 'number':
return value % this.length;
case 'string':
return value.toString()
.split("")
.reduce((sum, x) => sum + x.charCodeAt(0), 0) % this.length;
default:
throw new Error("Unexpected type. Valid types include: string, number.");
}
}
// if this.values is filled or if there are 3 elements in a given bucket we rebalance
// the values, rehashing and expanding this.values
rebalance() {
this.length = this.length ** 2;
this.count = this.length;
const valuesCopy = this.values;
this.values = new Array(this.length);
for (let bucket of valuesCopy) {
if (bucket) {
for (let slot of bucket) {
this.set(value);
}
}
}
}
// returns an element if it exists
// must be O(1)
get(value) {
return this.values[this.hash(value)]
.indexOf(value) !== -1;
}
// adds an element
// must be O(1)
set(value) {
const index = this.hash(value);
// for rebalancing, we need to know:
// 1. if the index's values are overflowing (3)
// 2. if this is the first value at an index
if (this.values[index]) {
this.values[index].push(value);
if (this.values[index].length === BUCKET_LIMIT) {
this.rebalance();
}
} else {
this.values[index] = [value];
this.count--;
}
}
}
@bvallelunga
Copy link

Notes

  • In interviews always try to be as explict as possible. this.length = this.length ** 2; => this.length = Math.pow(this.length, 2);
  • Try to break up your logic into multiple lines for readabliity

Before

 return value.toString()
                    .split("")
                    .reduce((sum, x) => sum + x.charCodeAt(0), 0) % this.length;

After

const index = value.toString().split("").reduce((sum, x) => (sum + x.charCodeAt(0)), 0) 
return index % this.length;
  • Use guarding logic to prevent nested structures.

Before

for (let bucket of valuesCopy) {
    if (bucket) {
        for (let slot of bucket) {
            this.set(value);
        }
    }
}

After

for (let bucket of valuesCopy) {
  if (!bucket) { continue }
  for (let slot of bucket) {
    this.set(value);
  }
}
  • Test your code. I think this code returns a boolean but not the value. This is unexpected behavior. IndexOf() always returns a boolean. Also If this.hash(value) returns an index not in the this.values then this function will return an error.
// returns an element if it exists
    // must be O(1) 
    get(value) {
        return this.values[this.hash(value)]
            .indexOf(value) !== -1;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment