編寫函數查找字符串數組中的最長公共前綴。若不存在公共前綴,返回空字符串 ""。
| 方法 | 思路 | 時間複雜度 | 備註 |
|---|---|---|---|
| 橫向掃描 | 以第一個串為基準,依次與其餘串比對縮短前綴 | O(S) | S 為所有字符總長,簡單直觀 |
| 縱向掃描 | 逐列比對所有串的第 i 個字符 | O(S) | 最壞情況同橫向,平均更快(提前終止) |
| 分治 | 左右半遞歸求 LCP,再合併 | O(S) | 適合並行化 |
| 二分查找 | 在第一個串長度上二分長度,驗證是否為公共前綴 | O(S log m) | m 為最短串長 |
| 排序法 | 排序後只需比對首尾兩串 | O(N log N * m) | 代碼極短,常數較大 |
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (strs.empty()) return "";
for (int i = 0; i < strs[0].size(); ++i) {
char c = strs[0][i];
for (int j = 1; j < strs.size(); ++j) {
if (i == strs[j].size() || strs[j][i] != c)
return strs[0].substr(0, i);
}
}
return strs[0];
}
};
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (strs.empty()) return "";
sort(strs.begin(), strs.end());
string &first = strs.front(), &last = strs.back();
int i = 0;
while (i < first.size() && i < last.size() && first[i] == last[i]) ++i;
return first.substr(0, i);
}
};
class Solution:
def longestCommonPrefix(self, strs):
if not strs: return ""
for i, chars in enumerate(zip(*strs)):
if len(set(chars)) > 1:
return strs[0][:i]
return min(strs) # 全匹配時返回最短串
# 分治法 44ms
def longestCommonPrefix(self, strs):
if not strs: return ""
def lcp(l, r):
if l == r: return strs[l]
mid = (l + r) // 2
left, right = lcp(l, mid), lcp(mid+1, r)
i = 0
while i < len(left) and i < len(right) and left[i] == right[i]: i += 1
return left[:i]
return lcp(0, len(strs)-1)
string_view (C++17) 或索引範圍延遲構造結果。O(S),S 為所有字符總數。O(1)(不計輸出),排序法 O(log N) 棧空間。