题目:
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: [“flower”,“flow”,“flight”] 输出: “fl”
示例 2:
输入: [“dog”,“racecar”,“car”] 输出: “” 解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
解题思路:
解法一:逐个比较
第一种方法就是暴力破解,让第一个字符串成为最长公共子串,从前往后依次比较,这种方法占内存,但是耗时不长
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
if(strs.length === 0 || strs === null){
return ""
}
let prevs = strs[0] //另第一个子串为公共前缀
for(let i=1;i<strs.length;i++){
let j=0
for(;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
};
解法二:分治策略 归并思想
分治算法,将一个复杂的问题,分成两个或多个相似的子问题,在把子问题分成更小的子问题,直到更小的子问题可以简单求解,求解子问题,则原问题的解则为子问题解的合并
这道题就是一个典型的分治策略问题:多个字符串的最长公共前缀为两两字符串的最长公共前缀的最长公共前缀,我们可以归并比较两最长公共前缀字符串的最长公共前缀,知道最后归并比较成一个,则为字符串数组的最长公共前缀
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
if(strs === null || strs.length === 0) {
return ""
}
return twoStr(strs)
// 求 str1 与 str2 的最长公共前缀
function twoCommonStr(str1,str2) {
let i = 0;
for(;i<str1.length && i<str2.length;i++){
if(str1.charAt(i) !== str2.charAt(i)){
break
}
}
return str1.substring(0,i)
}
// 分裂两个数组长度为1
function twoStr(arr){
let length = arr.length
if(length === 1){
return arr[0]
}
let mid = Math.floor(length/2)
let left = arr.slice(0,mid)
let right = arr.slice(mid,length)
return twoCommonStr(twoStr(left),twoStr(right)) //获取两个最长公共子串的长度
}
};