04.Keyboard Row

作者 iHugo 日期 2017-03-15
04.Keyboard Row

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

例子:

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

注意:

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

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

  1. 需要一个正确的正则表达式。
  2. 判断之前需要将单词转换成小写的。
  3. 将有效的单词收集并返回
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. 返回结果
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
    }
}