- 题目描述:最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-common-prefix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
- C++编程实现:
(1)水平扫瞄
思路
首先,我们将描述一种查找一组字符串的最长公共前缀 的简单方法。
我们将会用到这样的结论:
算法
为了运用这种思想,算法要依次遍历字符串 [S1…Sn],当遍历到第i个字符串的时候,找到最长公共前缀 LCP(S1…Si)。当 LCP(S1…Si)是一个空串的时候,算法就结束了。 否则,在执行了n次遍历之后,算法就会返回最终答案 LCP(S1…Sn)。
(2)二分查找法
这个想法是应用二分查找法找到所有字符串的公共前缀的最大长度 L。 算法的查找区间是 (0…minLen),其中 minLen 是输入数据中最短的字符串的长度,同时也是答案的最长可能长度。 每一次将查找区间一分为二,然后丢弃一定不包含最终答案的那一个。算法进行的过程中一共会出现两种可能情况:
S[1...mid] 不是所有串的公共前缀。 这表明对于所有的 j > i ,S[1..j] 也不是公共前缀,于是我们就可以丢弃后半个查找区间。
S[1...mid] 是所有串的公共前缀。 这表示对于所有的 i < j ,S[1..i] 都是可行的公共前缀,因为我们要找最长的公共前缀,所以我们可以把前半个查找区间丢弃。
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
int nsize = strs.size();
if (nsize < 1)
return "";
int minLen = INT_MAX;
for(int i=0; i<nsize; i++)
{
int nlen = strs[i].length();
minLen = min(minLen,nlen);
}
int low = 0;
int high = minLen;
while(low <= high)
{
int middle = (low+high)/2;
if (isCommonPre(strs,middle))
low = middle+1;
else
high = middle-1;
}
return strs[0].substr(0, (low+high)/2);
}
bool isCommonPre(vector<string>& strs, int npos)
{
string str0 = strs[0];
for(int i=1; i<strs.size(); i++)
{
for(int j=0; j<npos; j++)
{
if(str0[j] != strs[i][j])
return false;
}
}
return true;
}
};