leetcode-140-單詞拆分 II-java

題目及測試

package pid140;
/*單詞拆分 II

給定一個非空字符串 s 和一個包含非空單詞列表的字典 wordDict,在字符串中增加空格來構建一個句子,使得句子中所有的單詞都在詞典中。返回所有這些可能的句子。

說明:

    分隔時可以重複使用字典中的單詞。
    你可以假設字典中沒有重複的單詞。

示例 1:

輸入:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
輸出:
[
  "cats and dog",
  "cat sand dog"
]

示例 2:

輸入:
s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
輸出:
[
  "pine apple pen apple",
  "pineapple pen apple",
  "pine applepen apple"
]
解釋: 注意你可以重複使用字典中的單詞。

示例 3:

輸入:
s = "catsandog"
wordDict = ["cats", "dog", "sand", "and", "cat"]
輸出:
[]



*/

import java.util.ArrayList;
import java.util.List;

public class main {
	
	public static void main(String[] args) {
		String [] testTable = {"catsanddog","applepenapple","catsandog"};
		List<List<String>> testTable2=new ArrayList<List<String>>();
		List<String> list=new ArrayList<>();
		list.add("cat");
		list.add("cats");
		list.add("and");
		list.add("sand");
		list.add("dog");
		testTable2.add(list);
		list=new ArrayList<>();
		list.add("apple");
		list.add("pen");
		testTable2.add(list);
		list=new ArrayList<>();
		list.add("cats");
		list.add("dog");
		list.add("sand");
		list.add("and");
		list.add("cat");
		testTable2.add(list);
		
		for(int i=0;i<testTable.length;i++){
			test(testTable[i], testTable2.get(i));
		}

	}
		 
	private static void test(String ito,List<String> ito2) {
		Solution solution = new Solution();
		List<String> rtn;
		long begin = System.currentTimeMillis();
		System.out.print(ito);		    
		System.out.println();
		for(String str:ito2){
			System.out.print(str+" ");		  
		}
		System.out.println();
		//開始時打印數組
		
		rtn= solution.wordBreak(ito,ito2);//執行程序
		long end = System.currentTimeMillis();	
		
		System.out.println("rtn=" );
		for(String str:rtn){
			System.out.println(str+" ");		  
		}
		System.out.println();
		System.out.println("耗時:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(不成功,應該是對的,超時)

建立一個List<List<String>> lists,lists[i] 代表[0,i]的字符串,拆分後的字符串數組。

之前的[0,j],新的單詞(j,i],每次將之前的lists[j] 加上空格,加上符合要求的s.subString(j+1,i+1)

package pid140;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Solution {
	public List<String> wordBreak(String s, List<String> wordDict) {
		
		int length=s.length();
		if(length==0){
			return new ArrayList<String>();
		}
		Set<String> set=new HashSet<>(wordDict);
		// lists[i] 代表[0,i]的字符串,拆分後的字符串數組
		List<List<String>> lists=new ArrayList<>();
		for(int i=0;i<length;i++){
			lists.add(new ArrayList<>());
		}
		for(int i=0;i<length;i++){
			List<String> list=lists.get(i);
			for(int j=-1;j<i;j++){
				// 之前的[0,j],新的單詞(j,i]
				// j=-1,[0,-1],(-1,i]
				// j=0,[0,0],(0,i]
				// j=1,[0,1],(1,i]
				// j=i-1,[0,i-1],(i-1,i]
				if(j==-1){
					if(set.contains(s.substring(0, i+1))){
						list.add(s.substring(0, i+1));
					}
				}else{
					if(lists.get(j).size()>0&&set.contains(s.substring(j+1, i+1))){
						for(String str:lists.get(j)){
							list.add(str+" "+s.substring(j+1, i+1));
						}
					}
				}
			}
		}		       
		return lists.get(length-1);
    }
	

}

解法2(別人的)

這個方法背後的想法是對於給定的問題(s),它可以被拆分成子問題 s1s1s1 和 s2s2s2 。如果這些子問題分別都能滿足條件,那麼整個文字 s 也可以滿足。比方說, "catsanddog" 可以被拆分成子字符串 "catsand" 和 "dog" 。子問題 "catsand" 進一步可以被拆分成 "cats" 和 "and" ,它們分別都是字典的一部分,所以 "catsand" 也是滿足條件的。遞歸回來,因爲 "catsand" 和 "dog" 分別都滿足要求,所以原字符串 "catsanddog" 也符合要求。

現在,我們來考慮 dp  數組如何求出。我們使用長度爲 n+1n+1n+1 的數組 dp  ,其中 n 是給定字符串的長度。 dp[k] 被用來存儲用 s[0:k−1]可被拆分成合法單詞的句子。我們同事用兩個指針 i 和 j ,其中 i 表示子字符串 s′ 的長度(s′ 是 s 的一個前綴), j 表示 s′ 的拆分位置,即拆分成 s′(0,j) 和 s′(j+1,i) 。

爲了求出 dp  數組,我們將 dp[0] 初始化爲空串。我們以 i 爲結尾表示的子字符串的所有前綴,通過指針 j 將 s 拆分成 s1′ 和 s2′ 。爲了求出dp[i] ,我們檢查所有 dp[j] 包含的所有非空字符串,也就是所有能形成 s1′ 的句子。如果存在,我們進一步檢查 s2′ 是否在字典裏,如果兩個條件都滿足,我們將子字符串 s2′ 添加到所有 s1′ 的句子的後面(這些句子已經保存在了 dp[j] 裏面),並將這些新形成的句子保存進(dp[i])。最終, dp[n] (n 是給定字符串 s 的長度)裏面保存了所有可以得到完整字符串 s 的所有句子。

public class Solution {
   public List<String> wordBreak(String s, Set<String> wordDict) {
       LinkedList<String>[] dp = new LinkedList[s.length() + 1];
       LinkedList<String> initial = new LinkedList<>();
       initial.add("");
       dp[0] = initial;
       for (int i = 1; i <= s.length(); i++) {
           LinkedList<String> list = new LinkedList<>();
           for (int j = 0; j < i; j++) {
               if (dp[j].size() > 0 && wordDict.contains(s.substring(j, i))) {
                   for (String l : dp[j]) {
                       list.add(l + (l.equals("") ? "" : " ") + s.substring(j, i));
                   }
               }
           }
           dp[i] = list;
       }
       return dp[s.length()];
   }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發佈了509 篇原創文章 · 獲贊 66 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章