当前位置 : 首页 » 文章分类 :  算法  »  LeetCode.139.Word Break 单词拆分

LeetCode.139.Word Break 单词拆分

题目描述

139 Word Break
https://leetcode-cn.com/problems/word-break/

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

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

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。

示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
     注意你可以重复使用字典中的单词。

示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

解题过程

dp[i] 表示 s 中前 i 个字符 s[0...i-1] 组成的子串是否可以拆分为单词
判断 s[0...i-1] 是否可拆分为单词时,我们只需遍历 0 <= j <= i-1 并判断 j 分隔的两个单词 s[0...j-1]s[j...i-1] 是否分别可拆分为单词。其中,s[0...j-1] 是否可拆分为单词已记录在 dp[j] 中,只需判断 s[j...i-1] 是否是单词即可。
则有递推公式
dp[i] = dp[j] && dict.contains(s[j,i-1]), j = 0...i-1
初始条件 dp[0] = truedp[s.length] 就是最终结果

时间复杂度 O(n^2),空间复杂度 O(n)

private static class SolutionV202006 {
    public boolean wordBreak(String s, List<String> wordDict) {
        // dp[i] 表示 s 中前 i 个字符 s[0...i-1] 组成的子串是否可以拆分为单词,dp[s.length] 就是最终结果
        boolean[] dp = new boolean[s.length() + 1];
        dp[0] = true;
        Set<String> wordSet = new HashSet<>(wordDict);
        for (int i = 1; i <= s.length(); i++) {
            for (int j = i - 1; j >= 0; j--) {
                dp[i] = dp[j] && wordSet.contains(s.substring(j, i));
                if (dp[i]) {
                    break;
                }
            }
        }
        return dp[s.length()];
    }
}

GitHub代码

algorithms/leetcode/leetcode/_139_WordBreak.java
https://github.com/masikkk/algorithms/blob/master/leetcode/leetcode/_139_WordBreak.java


上一篇 Linode VPS 使用记录

下一篇 LeetCode.016.3Sum Closest 最接近的三数之和

阅读
评论
483
阅读预计2分钟
创建日期 2020-06-25
修改日期 2020-06-25
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论