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里面。

  • 相关阅读:
    关于CI/CD/CD (Continuous Integration/Continuous Delivery/Continuous Deployment)
    linux bash变量替换(# ## % %% / //)
    Azure静态公网ip自助反解
    Hadoop HDFS HA启动出现两个StandBy NameNode
    yum反查某个命令或so库在哪个包里面
    Hadoop 新建集群namenode format
    命令行web客户端与HTTP REST API调试工具
    Linux下source文件两种方法
    Redis配置参数汇总
    Jenkins RestAPI调用出现Error 403 No valid crumb was included in the request
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13396221.html
Copyright © 2011-2022 走看看