Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情
一、题目描述:
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
二、思路与实现:
思路一:横向扫描解题,借用官方题解的图片:
如果我们在没有遍历完所有字符串的时候,最长公共前缀已经变成空字符串了,则最长公共前缀一定是空串,因此不需要继续遍历剩下的字符串,直接返回空串即可。
时间复杂度为O(mn),其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量,无额外空间复杂度;
代码实现:
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function (strs) {
if (strs == null || !strs.length) return "";
// 默认公共前缀
let prefix = strs[0];
let n = strs.length;
// 获得两个字符串的最长公共前缀
const getlongestCommonPrefix = (str1, str2) => {
let minLen = Math.min(str1.length, str2.length);
let commonIndex = 0;
while (commonIndex < minLen && str1[commonIndex] == str2[commonIndex])
commonIndex++;
return str1.substr(0, commonIndex);
};
for (let i = 1; i < n; i++) {
prefix = getlongestCommonPrefix(prefix, strs[i]);
// 最长公共前缀是空串的情况,提前退出
if (!prefix.length) return prefix;
}
return prefix;
};
思路二:纵向扫描解题
从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较 如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function (strs) {
if (strs == null || !strs.length) return "";
let count = strs.length;
for (let i = 0; i < strs[0].length; i++) {
// 当前要比较的字符
let c = strs[0][i];
for (let j = 1; j < count; j++) {
// j从1开始,比较相同列上字符是否相等,如果不等则可以提前退出了
if (c != strs[j][i]) {
return strs[0].substring(0, i);
}
}
}
// 当strs字符串数组只有一个字符串的的时候,公共前缀默认为第0个
return strs[0];
};
三、总结:
除了以上横向与纵向解题,还可以用分治法或二分法,就不一一做解了(简单题重拳出击~)