• LeetCode 472 连接词


    给你一个 不含重复 单词的字符串数组 words ,请你找出并返回 words 中的所有 连接词

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

    示例 1:

    输入:words = ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"]
    输出:["catsdogcats","dogcatsdog","ratcatdogcat"]
    解释:"catsdogcats" 由 "cats", "dog" 和 "cats" 组成; 
         "dogcatsdog" 由 "dog", "cats" 和 "dog" 组成; 
         "ratcatdogcat" 由 "rat", "cat", "dog" 和 "cat" 组成。
    

    示例 2:

    输入:words = ["cat","dog","catdog"]
    输出:["catdog"]

    提示:

    • 1 <= words.length <= 104
    • 0 <= words[i].length <= 1000
    • words[i] 仅由小写字母组成
    • 0 <= sum(words[i].length) <= 105
    动态规划 + 字符串哈希
    // 保存字符串转换得到的哈希值
    static Set<Long> set = new HashSet<>();
    
    // 目的是转换成唯一的一个数字,131 是个不错的进制
    static int P = 131, OFFSET = 128;
    
    /**
     * DP  + 字符串哈希(将一个字符串转换成一个唯一的数字)
     *
     * @param words
     * @return
     */
    public static List<String> findAllConcatenatedWordsInADict(String[] words) {
        if (words == null || words.length == 0) return new ArrayList<>();
    
        set.clear();
        // 字符串哈希
        for (String word : words) {
            long hash = 0;
            for (char ch : word.toCharArray()) {
                hash = hash * P + (ch - 'a') + OFFSET;
            }
            set.add(hash);
        }
    
        List<String> ans = new ArrayList<>();
        for (String word : words) {
            if (check(word)) {
                ans.add(word);
            }
        }
        return ans;
    }
    
    /**
     * DP  判断字符串S是否为连接词
     *
     * @param s
     * @return
     */
    private static boolean check(String s) {
        if (s == null) return false;
    
        int n = s.length();
        // dp[i] 表示字符串s的前i个字符,能够切分的最大item数的个数
        int[] dp = new int[n + 1];
        Arrays.fill(dp, -1);
        // 初始状态
        dp[0] = 0;
        //从dp[i]出发,枚举范围[i+1,n],找到可由dp[i]所能更新的状态dp[j],并尝试使用dp[i]来更新dp[j]
        for (int i = 0; i <= n; i++) {
            if (dp[i] == -1) continue;
            long cur = 0;
            for (int j = i + 1; j <= n; j++) {
                cur = cur * P + (s.charAt(j - 1) - 'a') + OFFSET;
                // 状态转换,如果Set集合中包含由s[i~j]的字符串构成的哈希值,更新状态
                if (set.contains(cur)) dp[j] = Math.max(dp[j], dp[i] + 1);
            }
            if (dp[n] > 1) return true;
        }
        return false;
    }
    
    测试用例
    public static void main(String[] args) {
        String[] words = new String[]{"cat", "cats", "catsdogcats", "dog", "dogcatsdog", "hippopotamuses", "rat", "ratcatdogcat"};
        List<String> strings = FindAllConcatenatedWordsInADict.findAllConcatenatedWordsInADict(words);
        System.out.print("FindAllConcatenatedWordsInADict demo01 result : [");
        for (String str : strings) {
            System.out.print("," + str);
        }
        System.out.println("]");
    
        words = new String[]{"cat", "dog", "catdog"};
        strings = FindAllConcatenatedWordsInADict.findAllConcatenatedWordsInADict(words);
        System.out.print("FindAllConcatenatedWordsInADict demo02 result : [");
        for (String str : strings) {
            System.out.print("," + str);
        }
        System.out.println("]");
    }
    
    测试结果
    FindAllConcatenatedWordsInADict demo01 result : [,catsdogcats,dogcatsdog,ratcatdogcat]
    FindAllConcatenatedWordsInADict demo02 result : [,catdog]
    
  • 相关阅读:
    团队开发冲刺2.3(2015.5.27)
    团队开发冲刺2.2(2015.5.26)
    团队开发冲刺2.1(2015.5.26)
    团队开发冲刺1.6(2015.5.14)
    团队开发冲刺1.5(2015.5.13)
    团队开发冲刺1.4(2015.5.12)
    团队开发冲刺1.3(2015.5.11)
    团队开发冲刺1.2(2015.5.10)
    团队开发冲刺1.1(2015.5.9)
    找1
  • 原文地址:https://www.cnblogs.com/fyusac/p/15742616.html
Copyright © 2020-2023  润新知