你的第一段代码实际上并没有更高效。确实,它少了一个for
循环,但取而代之的是六个if
条件语句。这只是对固定大小数组的循环进行了展开,即所谓的“循环展开”。两种解决方案都具有常数复杂度(O(1))。
要真正提高效率,可以在接受一个单词后跳过检查其他行,并使用一些高级函数来提高代码可读性:
const rows = ["qwertyuiop", "asdfghjkl", "zxcvbnm"];
function findWords(words) {
return words.filter(word => {
return rows.some(row => {
return word.split('').every(letter => {
return row.includes(letter.toLowerCase());
});
});
});
}
为了使它在处理巨大字母表(不仅仅是26个英文字母)和同样庞大的键盘布局(不仅仅是3行,而是许多大行)时速度更快,避免遍历rows
以及其中每个字母的includes
检查。可以预先处理键盘布局为查找映射:
const rows = ["qwertyuiop", "asdfghjkl", "zxcvbnm"];
const rowByLetter = new Map(rows.flatMap(row =>
row.split('').map(letter => [letter, row])
));
function findWords(words) {
return words.filter(word => {
if (word.length <= 1) return true;
const row = rowByLetter.get(word[0].toLowerCase());
return word.slice(1).split('').every(letter =>
row === rowByLetter.get(letter.toLowerCase())
);
});
}