问题描述
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
例子:
输入: ["flower","flow","flight"]
输出: "fl"
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
输入: ["f"]
输出: "f"
分析
思路:
遍历数组,找出前两个串的公共前缀,再以此公共前缀为基础,与下一串一起找出两个串的公共前缀,依此类推,得到结果。
在实际实现中,以第一个串作为基础,其余所有串与此串比对,得到最长的公共子串为止。
使用二分查找法批量对比。
注意边界条件的判别。
代码
int find_min_len(char **s, int n)
{
int i, min = strlen(s[0]);
for (i = 1; i < n; i++) {
if (strlen(s[i]) < min) {
min = strlen(s[i]);
}
}
return min;
}
bool is_common_prefix(char **s, int n, char *str, int start, int end)
{
int i, j;
for (i = 1; i < n; i++) {
for (j = start; j <= end; j++) {
if ((s[i][j] == '\0') || (str[j] == '\0') || (s[i][j] != str[j])) {
return false;
}
}
}
return true;
}
char* longestCommonPrefix(char** s, int n) {
int len = 0;
int low = 0, high = 0, mid = 0;
int index = 0;
if (n < 1) {
return "";
} else if (n == 1) {
return s[0];
}
len = find_min_len(s, n);
if (len < 1) {
return "";
}
high = len;
/* 使用二分查找 */
while (low <= high) {
mid = low + (high - low + 1) / 2;/* 防止溢出,同(high + low + 1)/2 */
if (is_common_prefix(s, n, s[0], low, mid)) {
index = mid + 1;
low = mid + 1;
} else {
high = mid - 1;
}
}
s[0][index] = '\0';
return s[0];
}