题目地址
扫描,横着扫描、竖着扫描
暴力算法,双层循环,注意数组越界问题
分治
分别找出数组的前一半和后一半的最大公共前缀,他们的最大公共前缀即为答案。
在这里插入代码片
二分
关键就是如果前一半匹配,则考虑 前一半+后一半的一半 是否匹配,如果前一半不匹配,则考虑前一半的一半是否匹配,重复过程到结束
1、先找出最短的字符串的长度len
2、从left = 0,right = len开始
3、mid = (left +right)/2,
4、if isPrefix(0,mid) , then left = mid + 1, else right = mid - 1
5、重复 3、4直至left >= right;
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs == null || strs.length < 1) return "";
int len = strs[0].length();
for(String s : strs) {
len = Math.min(len, s.length());
}
int left = 0;
int right = len;
while(left < right) {
int mid = (left + right) / 2;
if(h(strs, mid)) {
left = mid + 1;
}else {
right = mid - 1;
}
}
return strs[0].substring(0, (right+ left) / 2);
}
private boolean h(String[] strs, int len) {
String p = strs[0].substring(0, len + 1);
for(int i = 0; i < strs.length; i ++) {
if(!strs[i].startsWith(p)) {
return false;
}
}
return true;
}
}
前缀树
public class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length <= 0 || strs[0].length() <= 0) return "";
Trie t = new Trie();
for(int i = 0; i < strs.length; i ++) {
t.insert(strs[i]);
}
return t.deepest(strs[0]);
}
class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
/** Inserts a word into the trie. */
public void insert(String word) {
TrieNode t = root;
for(int i = 0; i < word.length(); i ++) {
char c = word.charAt(i);
if(!t.containsKey(c)) {
t.put(c, new TrieNode());
}
t = t.get(c);
}
t.setEnd();
}
private TrieNode searchPrefix(String word) {
TrieNode t = root;
for(int i = 0; i < word.length(); i ++) {
char c = word.charAt(i);
if(t.containsKey(c)) {
t = t.get(c);
}else {
return null;
}
}
return t;
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
TrieNode t = searchPrefix(word);
return t != null && t.isEnd();
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
TrieNode t = searchPrefix(prefix);
return t != null;
}
public String deepest(String s) {
StringBuilder ans = new StringBuilder();
TrieNode t = root;
for(int i = 0; i < s.length(); i ++) {
char c = s.charAt(i);
if(t.containsKey(c) && t.getLinks() == 1 && !t.isEnd()) {
ans.append(c);
t = t.get(c);
}else {
break;
}
}
return ans.toString();
}
private class TrieNode{
private TrieNode[] links;
private boolean isEnd;
private int size;
private static final int R = 26;
public TrieNode() {
links = new TrieNode[TrieNode.R];
size = 0;
}
public boolean containsKey(char key) {
return links[key - 'a'] != null;
}
public TrieNode get(char ch) {
return links[ch - 'a'];
}
public void put(char ch, TrieNode node) {
if(!containsKey(ch)) size ++;
links[ch - 'a'] = node;
}
public boolean isEnd() {
return isEnd;
}
public void setEnd() {
isEnd = true;
}
public int getLinks() {
return size;
}
}
}
}