题目
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
解题思路
思路一 逐个对比
我们可以取第一个字符串为基准,进行两次for
循环。外层循环遍历数组中剩余的字符串元素,内层循环用以比较基准字符串和当前字符串元素中的公共部分,并重新确定基础字符串。
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
if (strs === null || strs.length === 0) return "";
var prevs = strs[0]
for(var i = 1; i < strs.length; i++) {
for(var j = 0 ; j < prevs.length && j < strs[i].length; j++) {
if(prevs.charAt(j) !== strs[i].charAt(j)) break
}
prevs = prevs.substring(0, j)
if(prevs === "") return ""
}
return prevs
};
思路二 分治算法
我们可以将一个复杂的问题,分成两个或者多个相似的子问题,把子问题分成更小的子问题。直到更小的子问题可以简单求解,求解子问题,则原问题的解为子问题的合并。
- 问题:求多个字符串的最长公共前缀
- 分解成多个相似的子问题:求两个字符串的最长公共前缀。
- 子问题可以简单求解
- 多个字符串的最长公共前缀为两两字符串的最长公共前缀的最长公共前缀。我们可以归并比较两最长公共前缀字符串的最长公共前缀,直到最后归并成为一个。
var longestCommonPrefix = function(strs) {
if (strs === null || strs.length === 0) return "";
return lCPrefixRec(strs)
};
// 若分裂后的两个数组长度不为 1,则继续分裂
// 直到分裂后的数组长度都为 1,
// 然后比较获取最长公共前缀
function lCPrefixRec(arr) {
var length = arr.length
if(length === 1) {
return arr[0]
}
var mid = Math.floor(length / 2),
left = arr.slice(0, mid),
right = arr.slice(mid, length)
return lCPrefixTwo(lCPrefixRec(left), lCPrefixRec(right))
}
// 求 str1 与 str2 的最长公共前缀
function lCPrefixTwo(str1, str2) {
var j = 0
for(; j < str1.length && j < str2.length; j++) {
if(str1.charAt(j) !== str2.charAt(j)) {
break
}
}
return str1.substring(0, j)
}