LeetCode系列记录我学习算法的过程。
持续创作,加速成长!这是我参与「掘金日新计划 6 月更文挑战」的第 13 天,点击查看活动详情
题目
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例:
输入: strs = ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
输入: strs = ["flower","flow","flight"]
输出: "fl"
思路
这题第一眼的思路就是从每一项的第一个字符开始匹配,相同则匹配下一个字符,直至没有字符可匹配或匹配的字符不相同
但仔细一想,这样操作的运算量太大了,肯定不是正常的解法
既然是公共前缀,那肯定是任意两项的公共前缀都包含了最终的公共前缀
那我们便可以从第一项开始,先记录第一项和第二项的公共前缀 res,然后找 res 和第三项的公共前缀并替换 res
当某一项匹配完后 res 的值为 '',或匹配完所有项后,返回结果,这样下来最多循环一次即可
代码实现
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
// 存储结果 先默认第一项是结果
let res = strs[0]
// 从第二项开始循环
for(let i = 1; i < strs.length; i++) {
// 取出字符串
const item = strs[i]
// 获取当前结果及当前字符串的较短长度
const len = Math.min(res.length, item.length)
// 用temp暂时存储结果
const temp = res
// 清空结果
res = ''
// 遍历两个字符串
for(let j = 0; j < len; j++) {
// 相同则存入结果
if(temp[j] === item[j]) {
res += temp[j]
} else {
// 否则跳出遍历
break
}
}
// 如果两个字符串没有公共前缀,则无需继续循环,直接返回空串
if(res === '') return ''
}
return res
};
优化
看了题解的方法也是和我差不多,但是循环里的操作可以再优化一下,不需要 temp 来暂时存储结果,直接记录匹配到的下标即可
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
// 存储结果 先默认第一项是结果
let res = strs[0]
// 从第二项开始循环
for(let i = 1; i < strs.length; i++) {
// 取出字符串
const item = strs[i]
// 获取当前结果及当前字符串的较短长度
const len = Math.min(res.length, item.length)
// 下标
let j = 0
// 遍历两个字符串
for(; j < len; j++) {
// 不同则跳出循环
if(res[j] !== item[j]) {
break
}
}
// 截取结果
res = res.substr(0, j)
// 如果两个字符串没有公共前缀,则无需继续循环,直接返回空串
if(res === '') return ''
}
return res
};