JAVA程序设计:连接词(LeetCode:472)

给定一个不含重复单词的列表,编写一个程序,返回给定单词列表中所有的连接词。

连接词的定义为:一个字符串完全是由至少两个给定数组中的单词组成的。

示例:

输入: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"]

输出: ["catsdogcats","dogcatsdog","ratcatdogcat"]

解释: "catsdogcats"由"cats", "dog" 和 "cats"组成; 
     "dogcatsdog"由"dog", "cats"和"dog"组成; 
     "ratcatdogcat"由"rat", "cat", "dog"和"cat"组成。
说明:

给定数组的元素总数不超过 10000。
给定数组中元素的长度总和不超过 600000。
所有输入字符串只包含小写字母。
不需要考虑答案输出的顺序。

思路:

方法一:暴力,,开了一个list,用来存储上一次能匹配到的所有位置。然后我们通过暴力遍历可以判断出当前位置能否匹配到。

class Solution {
    public List findAllConcatenatedWordsInADict(String[] words) {
        
    	Map map=new HashMap<>();
    	List ans=new ArrayList<>();
    	List list=new ArrayList<>();
    	
    	for(int i=0;i0 && list.get(list.size()-1)==words[i].length()-1)
    			ans.add(words[i]);
    	}
    	
    	return ans;
    }
}

方法二:优雅的暴力,set+爆搜

class Solution {
	
	private Set st=new HashSet<>();
	
    public List findAllConcatenatedWordsInADict(String[] words) {
        
    	st.addAll(Arrays.asList(words));
    	List ans=new ArrayList<>(words.length);
    	
    	for(String word : words) {
    		if(dfs(word,0,0))
    			ans.add(word);
    	}
    	
    	return ans;
    }
    
    private boolean dfs(String word,int idx,int cnt) {
    	
    	if(idx==word.length()) return cnt>1;
    	
    	for(int i=idx;i

方法三:前缀树(字典树)

class Solution {
	
	class Trie{
		private TreeNode root;
		
		class TreeNode{
			String val;
			TreeNode[] children;
			
			public TreeNode() {
				this.val=null;
				this.children=new TreeNode[26];
			}
		}
		
		Trie() {
			this.root=new TreeNode();
		}
		
		private void insert(String word) {
			TreeNode cur=root;
			for(int i=0;i findAllConcatenatedWordsInADict(String[] words) {
        
    	Trie trie=new Trie();
    	for(String word : words)
    		trie.insert(word);
    	
    	List ans=new ArrayList<>(words.length);
    	
    	for(String word : words)
    		if(trie.search(word,0))
    			ans.add(word);
    	
    	return ans;
    }
}

 

你可能感兴趣的:(JAVA程序设计:连接词(LeetCode:472))