comments | difficulty | edit_url |
---|---|---|
true |
Medium |
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. The mapping is shown in the diagram below:
![](https://fastly.jsdelivr.net/gh/doocs/leetcode@main/lcci/16.20.T9/images/17_telephone_keypad.png)Example 1:
Input: num = "8733", words = ["tree", "used"]
Output: ["tree", "used"]
Example 2:
Input: num = "2", words = ["a", "b", "c", "d"]
Output: ["a", "b", "c"]
Note:
num.length <= 1000
words.length <= 500
words[i].length == num.length
There are no number 0 and 1 in num
.
We consider a forward solution, which traverses each digit in the string
Instead, we can consider a reverse solution, which traverses the given word list, and for each word
The time complexity is
class Solution:
def getValidT9Words(self, num: str, words: List[str]) -> List[str]:
def check(w: str) -> bool:
return all(d[c] == num[i] for i, c in enumerate(w))
d = {c: d for c, d in zip(ascii_lowercase, "22233344455566677778889999")}
return [w for w in words if check(w)]
class Solution:
def getValidT9Words(self, num: str, words: List[str]) -> List[str]:
trans = str.maketrans(ascii_lowercase, "22233344455566677778889999")
return [w for w in words if w.translate(trans) == num]
class Solution {
public List<String> getValidT9Words(String num, String[] words) {
String s = "22233344455566677778889999";
int[] d = new int[26];
for (int i = 0; i < 26; ++i) {
d[i] = s.charAt(i);
}
List<String> ans = new ArrayList<>();
int n = num.length();
for (String w : words) {
boolean ok = true;
for (int i = 0; i < n; ++i) {
if (d[w.charAt(i) - 'a'] != num.charAt(i)) {
ok = false;
break;
}
}
if (ok) {
ans.add(w);
}
}
return ans;
}
}
class Solution {
public:
vector<string> getValidT9Words(string num, vector<string>& words) {
string s = "22233344455566677778889999";
int d[26];
for (int i = 0; i < 26; ++i) {
d[i] = s[i];
}
vector<string> ans;
int n = num.size();
for (auto& w : words) {
bool ok = true;
for (int i = 0; i < n; ++i) {
if (d[w[i] - 'a'] != num[i]) {
ok = false;
}
}
if (ok) {
ans.emplace_back(w);
}
}
return ans;
}
};
func getValidT9Words(num string, words []string) (ans []string) {
s := "22233344455566677778889999"
d := [26]rune{}
for i, c := range s {
d[i] = c
}
for _, w := range words {
ok := true
for i, c := range w {
if d[c-'a'] != rune(num[i]) {
ok = false
break
}
}
if ok {
ans = append(ans, w)
}
}
return
}
function getValidT9Words(num: string, words: string[]): string[] {
const s = '22233344455566677778889999';
const d: string[] = Array(26);
for (let i = 0; i < 26; ++i) {
d[i] = s[i];
}
const ans: string[] = [];
const n = num.length;
for (const w of words) {
let ok = true;
for (let i = 0; i < n; ++i) {
if (d[w[i].charCodeAt(0) - 97] !== num[i]) {
ok = false;
break;
}
}
if (ok) {
ans.push(w);
}
}
return ans;
}
class Solution {
func getValidT9Words(_ num: String, _ words: [String]) -> [String] {
let s = "22233344455566677778889999"
var d = Array(repeating: 0, count: 26)
for i in 0..<26 {
d[i] = Int(s[s.index(s.startIndex, offsetBy: i)].asciiValue! - Character("0").asciiValue!)
}
var ans: [String] = []
let n = num.count
for w in words {
var ok = true
for i in 0..<n {
let numChar = Int(num[num.index(num.startIndex, offsetBy: i)].asciiValue! - Character("0").asciiValue!)
if d[Int(w[w.index(w.startIndex, offsetBy: i)].asciiValue! - Character("a").asciiValue!)] != numChar {
ok = false
break
}
}
if ok {
ans.append(w)
}
}
return ans
}
}