Skip to content

Instantly share code, notes, and snippets.

@iynere
Last active May 11, 2017 15:39
Show Gist options
  • Save iynere/df6dfa02c237ee279b1d545d0391712f to your computer and use it in GitHub Desktop.
Save iynere/df6dfa02c237ee279b1d545d0391712f to your computer and use it in GitHub Desktop.
string permutation problem, tree implementation solution
// given the traditional correspondences between numbers & letters on a telephone, as follows:
const phone = {
'2': 'ABC',
'3': 'DEF',
'4': 'GHI',
'5': 'JKL',
'6': 'MNO',
'7': 'PQRS',
'8': 'TUV',
'9': 'WXYZ'
}
// & assuming you have a perfect function for determining whether a given string is a word:
function isWord(word) {
/* will check if word exists, return true or false */
}
// write a function that will take a 7-digit phone number string & return all possible words corresponding to that phone number (assume all phone numbers will contain only the digits 2-9)
/* as a simplified example, if we were given a 2-digit number, e.g., '23', the full set of possible strings would be:
['AD', 'AE', 'AF', 'BD', 'BE', 'BF', 'CD', 'CE', 'CF']
& our final set of words would be ['AD', 'BE'] */
const allWordsFromPhoneNum = phoneNum => {
let words = [],
phoneTree = new PhoneWordsTree(phoneNum[0], '')
// initialize our tree structure (see below) with an empty string & the first number in our phoneNumber string (this number is important, as it is used to determine the max number of children this initial tree node may have before insertion must move to an additional row)
// loop through every possible combination of digits (i) and associated letters (j)
for (let i = 0; i < 7; i++) {
// save the current digit & its associated 3 or 4 letters, for convenience
let digit = phoneNum[i],
letters = phone[digit]
for (let j = 0; j < letters.length; j++) {
// call our insert function (see below) with each digit/letter combination
phoneTree.insert(phoneNum[i+1] || null, letters[j])
}
}
// now we need to round up our potential words & select the ones that pass our dictionary function test
const getCompleteWords = treeNode => {
if (treeNode.children) {
// if a node has children, we have not yet reached a complete word—call function again recursively on each child
treeNode.children.forEach(childTree => {
getCompleteWords(childTree)
})
} else {
// no children means we're at a potential word, so use our imaginary perfect dictionary function
if (isWord(treeNode.word)) words.push(tree.word)
}
}
getCompleteWords(phoneTree)
return words
}
class PhoneWordsTree {
// initialize our tree with word, number (to determine max children length), and children (array of child tree nodes)
constructor(num, str) {
this.word = str
this.number = num
this.children = []
}
insert(num, str) {
if (this.children.length < phone[this.number].length) {
// if the children array is not yet full, simply push a new tree node into the root node's children array
this.children.push(new PhoneWordsTree(num, str))
return this
} else {
// array is full, move onto next row & call insert recursively on each child tree node
this.children.forEach(childTree => {
childTree.insert(num, this.word + str, )
})
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment