Last active
May 11, 2017 15:39
-
-
Save iynere/df6dfa02c237ee279b1d545d0391712f to your computer and use it in GitHub Desktop.
string permutation problem, tree implementation solution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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