中级农民
- 积分
- 118
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2015-3-4
- 最后登录
- 1970-1-1
|
Problem:
On old cell phones, users typed on a numeric keypad and the phone would provide a list of words that matched these numbers. Each digit mapped to a set of 0-4 letters. Implement an algorithm to return a list of matching words, given a sequence of digits. You are provided a list of valid words (provided in whatever data structure you'd like). The mapping is shown in the diagram below:
1 2 3
abc def
4 5 6
ghi jkl mno
7 8 9
pqrs tuv wxyz
0
EXAMPLE
Input: 8733 Output: tree, used
Analysis:
Solution 1: We can iterate through letter combinations and use Trie to store dictionary. Because Trie has quick search with prefix, and we can skip the combination if the prefix is not contained in dictionary.
Solution 2: We can get all number mapping of the words in dictionary, and return on lookup.
Code:
Solution 1:
```
public List<String> getWords(String number, TrieNode root){
List<String> words=helper(number,root,0,new ArrayList<String>(),new StringBuilder());
return words;
}
public List<String> words(String number,TrieNode node,int index,List<String> words,StringBuilder sb){
if(node.isEnd && index==number.length()-1){
words.add(sb.toString());
return;
}
char[] letters=numberToChars(number.charAt(index));
if(letters==null){return;}
for(char letter:letters){
if(node.children.containsKey(letter)){
sb.append(letter);
words(number,node.children.get(letter), index+1, words, sb);
}
}
}
public char[] numberToChars(char number){
if(number=='0'){return null;}
return keypad[number-'0'-1];
}
public char[][] keypad=new char[][]{
{}, {a,b,c}, {d,e,f},
{g,h,i}, {j,k,l}, {m,n,o},
{p,q,r,s}, {t,u,v}, {w,x,y,z},
{}
};
```
Solution 2:
```
public List<String> getWords(String number,String[] words){
Map<String,List<String>> mapping=getMapping(words);
return mapping.get(number);
}
Map<String,List<String>> getMapping(String[] words){
Map<String,List<String>> mapping=new HashMap<String,List<String>>();
char[] letterToDigit=new char[26];
createLetterToDigit(letterToDigit);
for(String word:words){
StringBuilder sb=new StringBuilder();
for(char letter:word){
sb.append(letterToDigit[letter-'a']);
}
if(!mapping.containsKey(sb.toString())){
mapping.put(sb.toString(),new ArrayList<String>());
}
mapping.get(sb.toString()).add(word);
}
return mapping;
}
char createLetterToDigit(char[] letterToDigit){
for(int i=0;i<keypad.length;i++){
if(keypad[i]!=null){
for(char letter:keypad[i]){
letterToDigit[letter-'a']=i+1;
}
}
}
}
public char[][] keypad=new char[][]{
{}, {a,b,c}, {d,e,f},
{g,h,i}, {j,k,l}, {m,n,o},
{p,q,r,s}, {t,u,v}, {w,x,y,z},
{}
};
```
|
|