CC12-拆分词句
目录
一、题目分析
二、解题思路
三、代码实现
四、代码解释
五、测试结果
在字符串处理问题中,判断一个字符串能否拆分成字典中的单词序列是比较经典的题目。今天我们就用动态规划的方法来解决 “拆分词句” 问题。
一、题目分析
给定一个字符串 s
和一组单词 dict
,判断 s
是否可以用空格分割成一个单词序列,使得单词序列中所有的单词都是 dict
中的单词(序列可以包含一个或多个单词)。例如,s = "nowcode"
,dict = ["now", "code"]
,返回 true
,因为可分割成 "now code"
。
二、解题思路
使用动态规划:
- 定义
dp[i]
表示字符串s
的前i
个字符是否可以被分割。 - 初始化
dp[0] = true
(空字符串可以被分割)。 - 对于每个位置
i
,遍历从0
到i - 1
的位置j
,如果dp[j]
为true
(前j
个字符可分割)且s.substring(j, i)
在字典dict
中,那么dp[i] = true
。
三、代码实现
import java.util.*;public class Solution {public boolean wordBreak(String s, Set<String> dict) {int n = s.length();// dp[i] 表示字符串 s 的前 i 个字符是否可以被分割boolean[] dp = new boolean[n + 1];// 空字符串可以被分割dp[0] = true;for (int i = 1; i <= n; i++) {for (int j = 0; j < i; j++) {// 如果前 j 个字符可以被分割,且 j 到 i 的子串在字典中if (dp[j] && dict.contains(s.substring(j, i))) {dp[i] = true;break;}}}return dp[n];}// 测试方法public static void main(String[] args) {Solution solution = new Solution();String s = "nowcode";Set<String> dict = new HashSet<>();dict.add("now");dict.add("code");boolean result = solution.wordBreak(s, dict);// 输出结果,预期为 trueSystem.out.println(result);}
}
四、代码解释
wordBreak
方法:- 首先获取字符串
s
的长度n
,创建动态规划数组dp
,长度为n + 1
。 - 初始化
dp[0] = true
,因为空字符串可被分割。 - 外层循环遍历字符串的每个位置
i
(从1
到n
),内层循环遍历从0
到i - 1
的位置j
。 - 若
dp[j]
为true
且子串s.substring(j, i)
在字典dict
中,设置dp[i] = true
并跳出内层循环。 - 最后返回
dp[n]
,表示整个字符串是否可被分割。
- 首先获取字符串
main
方法:构建测试用例,调用wordBreak
方法并输出结果。
五、测试结果
运行测试代码,输出结果为 true
,与预期一致,说明代码正确。
这种动态规划方法的时间复杂度为 O(n2)(两层循环),空间复杂度为 O(n)(动态规划数组),能够高效解决问题。