【Leetcode】139. 单词拆分

题目描述

【Leetcode】139. 单词拆分_第1张图片


// 139. 单词拆分

// 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可
// 以被空格拆分为一个或多个在字典中出现的单词。

// 说明:

// 拆分时可以重复使用字典中的单词。
// 你可以假设字典中没有重复的单词。


题解

// 动态规划
// 如果希望"leetcode"可以拆分,那么一定存在子字符串可以匹配,
// 这个子字符串可能是"l",可能是"le",可能是"lee",也可能是"leet",
// 我们构造boolean dp数组,用双for循环遍历s字符串的字符,i索引从头
// 到尾遍历子字符的右边界。j从i-1往左,遍历s的每个子字符的起始点。
// 如果对于"leetcode"来说,i j遍历到可以匹配的子字符串为"leet"(即"leet"
// 在wordDict中出现了),那么我们将dp[i]对应位置置true,此时dp[i]对应的
// 字符位置为"c"(s.substring(0, 5)才等于"leet",取不到下标5)。如下:
// 
// set = {"leet", "code"}
// s = "leetcode"
//       j i
//
//      0      1      2      3      4      5      6      7      8      9
// dp={true, false, false, false, false, true, false, false, false, false}
//               <-   j                    i    ->
//
// 实际上我们是判断s.substring(j, i)是否存在于wordDict,和dp[j]是否为true,
// 是否同时成立,成立则赋给dp[i]。dp[j]=true表示上一个子字符是否匹配的标记位,
// (从头遍历的"leet",所以上一个子字符串默认为"",所以dp[0]初始化为0),
// 也就是说,不仅需要判断"leet"是否匹配,还要从j索引对应的"l"开始截断,
// 判断"l"之前的上一个子字符串是否匹配。如果同时匹配,则置当前dp[i]为true,
// 继续循环遍历下去。
// 最后当dp[dp.length]位置为true,说明一定可以能够匹配wordDict的若干个子串,
// 他们能够拼接成s字符串。返回dp[dp.length]/dp[s.length()]即可。

class Solution {
    public HashSet set;
	
    public boolean wordBreak(String s, List wordDict) {
        boolean[] dp = new boolean[s.length() + 1];
		set = new HashSet(wordDict);
        dp[0] = true;

        for(int i = 1; i <= s.length(); i++) {
            for(int j = i - 1; j >= 0; j--) {
                dp[i] = dp[j] && check(s.substring(j, i));
                if(dp[i])
					break;
            }
        }
        return dp[s.length()];
    }

    public boolean check(String s) {
        return set.contains(s);
    }
}


你可能感兴趣的:(#,Leetcode,算法与数据结构,字符串,列表,leetcode,java,数据结构)