题目描述
题解
水平扫描
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
string result = "";
if (size(strs) == 0) return result;
if (size(strs) == 1) {
result = strs[0];
return result;
}
string first = strs[0];
for (int i = 1; i < size(strs); ++i) {
string temp = strs[i];
int size = first.size() >= temp.size() ? temp.size() : first.size();
for (int j = 0; j < size; ++j) {
if (first[j] == temp[j]) {
result += first[j];
}
else break;
}
first = result;
result = "";
}
result = first;
return result;
}
};
复杂度分析
-
时间复杂度: O ( S ) O(S) O(S), S S S 是所有字符串中字符数量的总和。
最坏情况下,输入数据为 n n n 个长度为 m m m 的相同字符串,算法会进行 S = m ∗ n S = m*n S=m∗n 次比较。可以看到最坏情况下,本算法的效率与算法一相同,但是最好的情况下,算法只需要进行 n ∗ m i n L e n n*minLen n∗minLen 次比较,其中 m i n L e n minLen minLen 是数组中最短字符串的长度。 -
空间复杂度: O ( 1 ) O(1) O(1) ,我们只需要使用常数级别的额外空间。
字典树
public String longestCommonPrefix(String q, String[] strs) {
if (strs == null || strs.length == 0)
return "";
if (strs.length == 1)
return strs[0];
Trie trie = new Trie();
for (int i = 1; i < strs.length ; i++) {
trie.insert(strs[i]);
}
return trie.searchLongestPrefix(q);
}
class TrieNode {
// 子节点的链接数组
private TrieNode[] links;
private final int R = 26;
private boolean isEnd;
// 非空子节点的数量
private int size;
public void put(char ch, TrieNode node) {
links[ch -'a'] = node;
size++;
}
public int getLinks() {
return size;
}
// 假设方法 containsKey、isEnd、get、put 都已经实现了
// 可以参考文章:https://leetcode.com/articles/implement-trie-prefix-tree/
}
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
// 假设方法 insert、search、searchPrefix 都已经实现了
// 可以参考文章:https://leetcode.com/articles/implement-trie-prefix-tree/
private String searchLongestPrefix(String word) {
TrieNode node = root;
StringBuilder prefix = new StringBuilder();
for (int i = 0; i < word.length(); i++) {
char curLetter = word.charAt(i);
if (node.containsKey(curLetter) && (node.getLinks() == 1) && (!node.isEnd())) {
prefix.append(curLetter);
node = node.get(curLetter);
}
else
return prefix.toString();
}
return prefix.toString();
}
}
复杂度分析
最坏情况下查询字符串 q q q 的长度为 m m m 并且它与数组中 n n n 个字符串均相同。
-
时间复杂度:预处理过程 O ( S ) O(S) O(S),其中 S S S 数组里所有字符串中字符数量的总和,最长公共前缀查询操作的复杂度为 O ( m ) O(m) O(m)。
建立字典树的时间复杂度为 O ( S ) O(S) O(S)。在字典树中查找字符串 q q q 的最长公共前缀在最坏情况下需要 O ( m ) O(m) O(m) 的时间。 -
空间复杂度: O ( S ) O(S) O(S),我们只需要使用额外的 S S S 空间建立字典树。