1. 程式人生 > >Leetcode 472.連接詞

Leetcode 472.連接詞

div 復雜度 哈希 res i+1 pre -i 宋體 nat

連接詞

給定一個不含重復單詞的列表,編寫一個程序,返回給定單詞列表中所有的連接詞。

連接詞的定義為:一個字符串完全是由至少兩個給定數組中的單詞組成的。

示例:

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

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

解釋: "catsdogcats"由"cats", "dog" 和 "cats"組成;

"dogcatsdog"由"dog", "cats"和"dog"組成;

"ratcatdogcat"由"rat", "cat", "dog"和"cat"組成。

說明:

  1. 給定數組的元素總數不超過 10000。
  2. 給定數組中元素的長度總和不超過 600000。
  3. 所有輸入字符串只包含小寫字母。
  4. 不需要考慮答案輸出的順序。

思路是:

對於words中的每個單詞w,我們定義一個數組dp[n+1],如果dp[i] == true,則表示w.substr(0, i)可以由words中的已有單詞連接而成。那麽狀態轉移方程就是:dp[i] = {dp[j] && w.substr(j + 1, i - j) is in words},其中j < i。最終檢查dp[n]是否為true,如果是則將其加入結果集中。為了加速對words中的單詞的查找,我們用一個哈希表來保存各個單詞。這樣時間復雜度可以降低到O(n * m^2),其中n是words中的單詞的個數,m是每個單詞的平均長度(或者最大長度?)。

 1 import java.util.*;
 2 
 3 class Solution {
 4     public List<String> findAllConcatenatedWordsInADict(String[] words) {
 5         Set<String> set=new HashSet<String>();
 6         for(int i=0;i<words.length;i++){
 7             set.add(words[i]);
 8         }
 9         List<String> res=new
ArrayList<String>(); 10 for(String word:words){ 11 int n=word.length(); 12 boolean[] dp=new boolean[n+1]; 13 Arrays.fill(dp,false); 14 dp[0]=true; 15 for(int i=0;i<n;i++){ 16 if(!dp[i]) continue; 17 for(int j=i+1;j<=n;j++){ 18 if(j-i<n && set.contains(word.substring(i,j))){ 19 dp[j]=true; 20 } 21 } 22 if(dp[n]){ 23 res.add(word); 24 break; 25 } 26 } 27 } 28 return res; 29 } 30 }

Leetcode 472.連接詞