首先解读一下这道题目,简单来说就是一个字符串数组中的字符串不限制使用次数,是否能拼成目标字符串s。
本题乍一看很难,看到第一眼想到的就是暴力解法,但是很明显这道题的目的不是让我们直接暴力的,当然暴力解法也是会超时的。
因为本题是动态规划背包问题中的,因此我们也不想其他方法了,就按照动态规划背包问题来思考。
目光再次转到题目上,字符串数组相当于物品数组,目标字符串s相当于背包,本题的目标就是是否能正好装满背包。不限制数组中元素的使用,那么这道题就是完全背包问题,而且目标字符串s是有顺序的,因此本题也是排列问题,因此需要先循环目标字符串s,然后循环物品数组。
那么问题就是本题是是字符串,与普通背包问题有一定的区别,前面的代码都是和平常一样,创建一个长度为s.length+1的数组,根据题意初始值可设置为false,而为了解出本道题,arr[0]要初始化为true。之后就是循环体内的代码,判断当遍历出的字符串长度大于等于相应字符串数组元素长度时,需要判断截出的字符串是否与该对应字符串数组是否相等并且截取字符串之前的字符串是否已经寻找成功,如果同时也成功,那么当前字符串对应的最后一位所对应的创建数组位赋值为true。
最终返回自创数组的第s.length个的值即可。
代码如下:
var wordBreak = function (s, wordDict) {
let arr = new Array(s.length + 1).fill(0)//创建arr数组,初始值为false用0替代
arr[0] = 1//arr[0]初始为true,用1表示。
for (let j = 0; j <= s.length; j++) {//遍历字符串
for (let i = 0; i < wordDict.length; i++) {//遍历数组
if (j >= wordDict[i].length) {//当遍历的字符长度能够大于等于当前数组元素长度时
if (s.slice(j - wordDict[i].length, j) === wordDict[i] && arr[j -wordDict[i].length]) {//截取字符串如果等于当前数组元素,并且此时数组arr对应元素为0
arr[j] = 1
}
}
}
}
return arr[s.length] ? true : false
};