zoukankan      html  css  js  c++  java
  • 472. Concatenated Words

    Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words.

    A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array.

    Example:

    Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"]
    
    Output: ["catsdogcats","dogcatsdog","ratcatdogcat"]
    
    Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; 
    "dogcatsdog" can be concatenated by "dog", "cats" and "dog";
    "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat".

    Note:

    1. The number of elements of the given array will not exceed 10,000
    2. The length sum of elements in the given array will not exceed 600,000.
    3. All the input string will only include lower case letters.
    4. The returned elements order does not matter.
    class Solution {
        private static Node root;
        
        public List<String> findAllConcatenatedWordsInADict(String[] words) {
            if (words == null || words.length == 0)
                return new ArrayList<>();
            
            root = new Node();
            buildTrie(words);
            
            List<String> result = new LinkedList<>();
            for (String word : words) {
                if (isConcatenated(word, 0, 0))
                    result.add(word);
            }
            return result;
        }
        
        // Return true if word starting from index is concatenated
        boolean isConcatenated(String word, int index, int countConcatenatedWords) {
            if (index == word.length())
                return countConcatenatedWords >= 2;
            
            Node ptr = root;
            for (int i = index; i < word.length(); i++) {
                if (ptr.children[word.charAt(i) - 'a'] == null) 
                    return false;
                ptr = ptr.children[word.charAt(i) - 'a'];
                
                if (ptr.isWordEnd)
                    if (isConcatenated(word, i + 1, countConcatenatedWords + 1))
                        return true;
            }
            
            return false;
        }
        
        private void buildTrie(String[] words) {
            Node ptr;
            for (String word : words) {
                ptr = root;
                for (char ch : word.toCharArray()) {
                    int order = ch - 'a';
                    if (ptr.children[order] == null) {
                        ptr.children[order] = new Node();
                    } 
                    ptr = ptr.children[order];
                }
                ptr.isWordEnd = true;
            }
        }
        
        class Node {
            Node[] children;
            boolean isWordEnd;
            
            public Node() {
                children = new Node[26];
                isWordEnd = false;
            }
        }
    }

    Trie!!!屌!@!!https://leetcode.com/problems/concatenated-words/discuss/176805/Trie-with-Explanations

    膜拜,首先把words存成trie,然后递归调用函数来检查是否当前word可以被concat成两个或以上,

    class Solution {
        public List<String> findAllConcatenatedWordsInADict(String[] words) {
            Set<String> prev = new HashSet();
            List<String> res = new ArrayList();
            if(words.length == 0 || words == null) return res;
            Arrays.sort(words, (a, b) -> a.length() - b.length());
            
            for(String word: words) {
                if(help(word, prev)) res.add(word);
                prev.add(word);
            }
            return res;
        }
        
        public boolean help(String word, Set<String> prev) {
            if(prev.isEmpty()) return false;
            int n = word.length();
            boolean dp[] = new boolean[n + 1];
            dp[0] = true;
            
            for(int i = 1; i <= n; i++) {
                for(int j = 0; j < i; j++) {
                    if(dp[j] && prev.contains(word.substring(j, i))) {
                         dp[i] = true;
                        break;
                    }
                }
            }
            return dp[n];
        }
    }

    阳间方法,类似word break,先把string 按长短排列,然后每个string判断能不能由后面的concat成,能就加到res里面。

  • 相关阅读:
    如何通过setTimeout理解JS运行机制详解
    css3系列之伪类选择器
    css3系列之属性选择器
    css3系列之伪元素选择器
    css3系列之兄弟选择器
    作为了解系列之 预处理器 和 后处理器
    网络系列之跨域
    网络系列之 cookie增删改查(封装)
    网络系列之 jsonp 百度联想词
    网络系列之 什么是ajax 封装ajax
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13396221.html
Copyright © 2011-2022 走看看