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

  • 相关阅读:
    php使用时间戳保存时间的意义
    php输出控制函数存在的意义
    php中foreach使用引用的陷阱
    mac下php添加openssl扩展
    gitlab配置自动同步
    lnmp集成环境tp nginx vhost配置
    上传文件中文文件名乱码的解决方法以及iconv函数的使用
    php返回数据格式
    怎样让Git忽略当前已经更改的文件
    connect() php-cgi.sock failed (2: No such file or directory)
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13396221.html
Copyright © 2020-2023  润新知