04.Keyboard Row

给定一组单词,返回所有字母都在同一行美国键盘上的单词。

例子:

Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]

注意:

  1. 可以使用同一个键盘上字母多次
  2. 假设输入有且只有字母

解决思路有两种。最简单的方法是利用正则表达式来判断字母是否满足正则表达式,如果满足则表示单词有效。这里面有几点需要注意的。

  1. 需要一个正确的正则表达式。
  2. 判断之前需要将单词转换成小写的。
  3. 将有效的单词收集并返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {    
func findWords(_ words: [String]) -> [String] {
// 利用正则表达式来判断
let pattern = "^([qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*)$"
var validateWords = [String]()
for word in words {
let lowerWord = word.lowercased()

let regex = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let matches = regex?.matches(in: lowerWord, options: .reportProgress, range: NSMakeRange(0, lowerWord.characters.count))
if let m = matches, m.count > 0 {
validateWords.append(word)
}
}
return validateWords
}
}

第二种方法就麻烦一点了。

  1. 首先将单词设置成有效
  2. 找到第一个字母在键盘的那一行。
  3. 接着判断所有字母是否是在那一行,如果不在则单词无效。
  4. 返回结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
func findWords(_ words: [String]) -> [String] {
// 1. 判断单词属于num行
// 2. 标示单词有效
// 3. 如果单词不属于num行
// 4. 标示单词无效
let lines: [String] = ["qwertyuiop", "asdfghjkl", "zxcvbnm"];
var validateWords = [String]()
for word in words {
let lowerWord = word.lowercased()
validateWords.append(word)

for line in lines {
if !line.characters.contains(lowerWord[lowerWord.startIndex]) {
continue
}

for c in lowerWord.characters {
if !line.characters.contains(c) {
validateWords.popLast()
break
}
}
}
}
return validateWords
}
}