LeetCode 14. Longest Common Prefix题解

题目地址

扫描,横着扫描、竖着扫描

暴力算法,双层循环,注意数组越界问题

分治

分别找出数组的前一半和后一半的最大公共前缀,他们的最大公共前缀即为答案。
在这里插入代码片

二分

关键就是如果前一半匹配,则考虑 前一半+后一半的一半 是否匹配,如果前一半不匹配,则考虑前一半的一半是否匹配,重复过程到结束

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;
	    	}
	    }
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值