Longest Common Prefix 五种解法(JAVA)
解法一:水平扫描
int indexOf(String str): 在字符串中检索str,返回其第一出现的位置,如果找不到则返回-1
class Solution { public String longestCommonPrefix(String[] strs) { if(strs.length == 0) return ""; String prefix = strs[0]; for(int i = 1; i < strs.length; i++){ while(strs[i].indexOf(prefix) != 0){ prefix = prefix.substring(0, prefix.length()-1); if(prefix.isEmpty()) return ""; } } return prefix; } }
解法二:垂直扫描
class Solution { public String longestCommonPrefix(String[] strs) { if(strs.length == 0) return ""; for(int i = 0; i < strs[0].length(); i++){ char c = strs[0].charAt(i); for(int j = 1; j < strs.length; j++){ if(strs[j].length() == i || strs[j].charAt(i) != c) //!!!关键点 return strs[0].substring(0, i); } } return strs[0]; } }
解法三:分治法
class Solution { public String longestCommonPrefix(String[] strs) { if(strs.length == 0) return ""; return subprefix(strs, 0, strs.length-1); } public String subprefix(String[] strs, int left, int right){ if(left >= right) return strs[left]; int mid = (left + right) / 2; String lsub = subprefix(strs, left, mid); String rsub = subprefix(strs, mid+1, right);//!!!分治法 int min = Math.min(lsub.length(), rsub.length()); for(int i = 0; i < min; i++){ if(lsub.charAt(i) != rsub.charAt(i)) return lsub.substring(0, i); } return lsub.substring(0, min); } }
解法四:二分搜索法
public boolean startsWith(String prefix, int toffset) prefix -- 前缀。 toffset -- 字符串中开始查找的位置
class Solution { public String longestCommonPrefix(String[] strs) { if(strs.length == 0) return ""; int minlen = Integer.MAX_VALUE; for(String str : strs) minlen = Math.min(minlen, str.length()); int low = 1; //这里指第一个字符串 int high = minlen; while(low <= high){ int mid = (low+high)/2; if(isCommonPrefix(strs, mid)){ low = mid+1;//+1 } else{ high = mid-1;//-1 } } return strs[0].substring(0, (low+high)/2); } public boolean isCommonPrefix(String[] strs, int len){ String str1 = strs[0].substring(0, len); for(int i = 1; i < strs.length; i++) if(!strs[i].startsWith(str1)) return false; return true; } }
解法五:Tire树
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 { // R links to node children private TrieNode[] links; private final int R = 26; private boolean isEnd; // number of children non null links private int size; public void put(char ch, TrieNode node) { links[ch -'a'] = node; size++; } public int getLinks() { return size; } //assume methods containsKey, isEnd, get, put are implemented as it is described //in https://leetcode.com/articles/implement-trie-prefix-tree/) } public class Trie { private TrieNode root; public Trie() { root = new TrieNode(); } //assume methods insert, search, searchPrefix are implemented as it is described //in 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(); } }