版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aaaaaaliang/article/details/89304749
题目描述
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
解决方案
方法一:横向扫描
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
const L = strs.length;
if( L === 0 || L === 1){
return L === 1 ? strs[0] : "" ;
}
let i = 1, pre = strs[0];
for(i; i < L; i++){
while(strs[i].indexOf(pre) !== 0){
pre = pre.substring(0, pre.length - 1)
if(pre === ""){return ""}
}
}
return pre
};
方法二:纵向扫描
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
const L = strs.length;
if( L === 0 || L === 1){
return L === 1 ? strs[0] : "" ;
}
let i = 0, SL = strs[0].length, pre = "";
for(i; i < SL; i++){
let char = strs[0][i], j = 1;
for(j;j<L;j++){
if(i === strs[j].length || char !== strs[j][i]){
return pre
}
}
pre += strs[0][i]
}
return pre
};
方法三:分治
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
if (!strs || strs.length === 0) {
return '';
} else {
return getPreByDivideArrFn(strs, 0, strs.length - 1);
}
// 拆分
function getPreByDivideArrFn(arr, l, r) {
if (l === r) {
return arr[l];
} else {
const mid = parseInt((l + r) / 2);
// 递归直到返回一个字符串,也就是l===r的时候
const leftStr = getPreByDivideArrFn(strs, l, mid);
const rightStr = getPreByDivideArrFn(strs, mid + 1, r);
return compareStrFn(leftStr, rightStr);
}
// 对比两个字符串,得到头门的最长公共前缀
function compareStrFn(leftStr, rightStr) {
let min = Math.min(leftStr.length, rightStr.length),
i = 0;
for (i; i < min; i++) {
if (leftStr[i] !== rightStr[i]) {
return leftStr.substr(0, i);
}
}
return leftStr.substr(0, min);
}
}
};
方法四:二分查找法
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
if (!strs || strs.length === 0) {
return '';
}
let i = 0,
L = strs.length,
minLen = Math.pow(2, 53);
// 获得数组成员的最小长度
for (i; i < L; i++) {
minLen = Math.min(minLen, strs[i].length);
}
let low = 1,
high = minLen;
while (low <= high) {
// 二分 将最小长度二分
let middle = parseInt((low + high) / 2);
if (isCommonPrefix(strs, middle)) {
// 如果左边都属于前缀,则将右边继续进行二分
low = middle + 1;
} else {
// 如果左边不都属于前缀,则将左边继续进行二分
high = middle - 1;
}
}
return strs[0].substr(0, parseInt((low + high) / 2));
function isCommonPrefix(strs, len) {
// 取数组第一个作为二分的字符串
let str1 = strs[0].substr(0, len),
i = 0,
L = strs.length;
for (i; i < L; i++) {
if (!strs[i].startsWith(str1)) {
return false;
}
}
return true;
}
};
更进一步
让我们看一个有些不同的问题:
给定一些键值字符串 S = [S 1 ,S 2 …S n ],我们要找到字符串 q 与 S 的最长公共前缀。 这样的查询操作可能会非常频繁。
思路是先将S的信息存储在一棵字典树里面,我们在这课数里面,匹配q的最长公共前缀