原题:
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode"
,
dict = ["leet", "code"]
.
Return true because "leetcode"
can be segmented as "leet code"
.
这个题使用的思想是动态规划,以前没有做过动态规划的题目,这里记录一下。动态规划的定义是:
"dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems."
即动态规划的思想是将一个大问题转化为一些规模较小的子问题,通过解决这些小问题,再将结果合并来解决大问题。这里不再具体探讨动态规划的思想,可以参考下面链接学习,这里就题论题一下:
一个知乎网友关于动态规划的回答:http://www.zhihu.com/question/23995189
就这个题目来说,首先设置一个标记数组book[s.len+1],数组值book[i]表示字符串从下标0到下标i的子字符串能否被切分(这是一个子问题),如果book[i]为真,也就是字符串从0到i的子字符串可以被切分,而且字符串从下标i+1开始到末尾的子字符串在dict中存在一个单词的话,那么真个字符串可以被切分。
其实真个问题是以此求book[1]、book[2]、...、book[len+1]的过程,book[len+1]的值的含义就是整个字符串s能否被切分,也就是我们最终想要的结果,但是想知道book[len+1]的值必须先知道它前面的值。book[0]默认为true。程序代码如下:
import java.util.Set; public class Solution { public static boolean wordBreak(String s, Set<String> wordDict) { int len = s.length(); boolean[] book = new boolean[len+1]; //用book[i]表示从0到下标i的子字符串能否被成功切割, book[0] = true; //则book[n]即表示整个字符串能否被切割能否 for(int i=1;i<=len;i++){ book[i] = false; } for(int i=0;i<len;i++){ for(int j=i;j>=0;j--){ if(book[j] && wordDict.contains(s.substring(j, i+1))){ book[i+1] = true; //这样就表示从1到i+1可以被切分,不需要再计算 break; } } } return book[len]; } // public static void main(String[] args) { // String str = "aaaaaaa"; // Set<String> set = new HashSet<String>(); // set.add("aaaa"); // set.add("aaa"); // System.out.println(wordBreak(str,set)); // } }