一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第28天,点击查看活动详情。
放假的第一天,起飞了
单词拆分
该题出自力扣的139题 —— 单词拆分【中等题】
审题
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
- 题意并不难理解,就是给出一个字符串和一个字符串列表,根据列表中的字符串是否能拼成一个完整的目标字符串返回布尔值
- 感觉就是经典的背包问题,不管是字符串就是目标值,列表就是背包,那么自然而然就会联想到动态规划的解法
- 解法:动态规划
- 首先定义一个布尔的数组,存储的长度是字符串的长度加一,是因为数组从0开始的,所以初始下标为1
- 默认数组的0下标为true,因为0个字符的时候一定能匹配成功
- 循环列表,下标从1开始,寓意着字符串的第一个字符开始
- 再度循环,在循环条件内判断
- 如果数组的当前值存在,并且列表存在这个字符串的子串
- 则把当前的字符下标赋值为true
- 最终返回数组的字符串长度下标
- 不能把动态规划想象成太复杂的问题,其实就是分治回溯的解法,把大问题拆分成小问题,并且找到规律。回溯 和 动态规划最大的区别在于,回溯是一头扎到底,如果不符合就回退;动态规划是拆分成小问题,每一个题解都与上一个题解存在关系,这可以联想到背包问题的二维数组。
编码
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int n = s.length();
boolean[] dp = new boolean[n+1];
dp[0] = true;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && wordDict.contains(s.substring(j,i))){
dp[i] = true;
break;
}
}
}
return dp[n];
}
}