动态规划、递归的典例
Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
For example, given
s =”catsanddog”,
dict =[“cat”, “cats”, “and”, “sand”, “dog”].
A solution is[“cats and dog”, “cat sand dog”].
让你把字符串拆解,每个拆解部分都是右侧Set里的元素
析:根据上一题可以求出所有的下标j,使得从(j,末尾)满足是集合中的元素。对于字符串s,如果s整体在集合中,加入List,之后在s中找断开的位置,将满足的字符串加入到List,
本题用到: 动态规划与递归
package com.yixin.exam;
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner sc= new Scanner(System.in);
Main main = new Main();
String s="catsanddog";
String[] ss ={"cat", "cats", "and", "sand", "dog"};
Set<String> dict = new HashSet<>();
for(String t:ss)
dict.add(t);
System.out.println(main.wordBreak(s,dict));
}
public ArrayList<String> wordBreak(String s, Set<String> dict) {
List<Integer> indexList = wordBreak2(s,dict);
ArrayList<String> res = wordBreak1(s,dict,0,indexList);
return res;
}
// 注:比如求出的indexList为7,4,2,0;
// firstIndex为当前需要分割的字串的首字母的下标
public ArrayList<String> wordBreak1(String s, Set<String> dict,int firstIndex,List<Integer> indexList) {
ArrayList<String> res = new ArrayList<>();
String subStr = s.substring(firstIndex);
if(dict.contains(subStr))
res.add(subStr);
//
int pos = indexList.indexOf(firstIndex);
for(int j=pos-1;j>=0;j--){
// laterIndex表示下一个可以分割的位置,比如0之后是2,2之后是4
int laterIndex = indexList.get(j);
subStr =s.substring(firstIndex,laterIndex);
if(dict.contains(subStr)){
ArrayList<String> innerRes = wordBreak1(s,dict,laterIndex,indexList);
for(String t:innerRes){
res.add(subStr+" "+t);
}
}
}
return res;
}
// 求出能够分割的点使点的右侧在集合中,参见上一题
public List<Integer> wordBreak2(String s, Set<String> dict) {
int n = s.length();
List<Integer> indexList = new ArrayList<>();
for(int i=n-1;i>=0;i--){
if(dict.contains(s.substring(i)))
indexList.add(i);
else
for(Integer t:indexList){
if(dict.contains(s.substring(i,t))){
indexList.add(i);
break;
}
}
}
return indexList;
}
}