【动态规划】Leetcode 139. 单词拆分【中等】

文章介绍了如何使用动态规划算法解决字符串s是否能由给定字典中的单词拼接的问题,通过构建布尔数组dp并进行状态转移计算,最后给出Java实现和时间空间复杂度分析。
摘要由CSDN通过智能技术生成

单词拆分

  • 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:

输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以由 “leet” 和 “code” 拼接成。

解题思路

这个问题可以使用动态规划来解决。

  • 1、我们定义一个长度为 s.length()+1 的布尔数组 dp,其中 dp[i] 表示字符串 s 的前 i 个字符是否可以被字典中的单词拼接而成。
    动态规划的状态转移方程为:

  •  dp[i] = dp[j] && wordDict.contains(s.substring(j, i)),其中 0 <= j < i
    

    这个方程的意思是,如果存在一个 j,使得 dp[j] 为 true并且字典中包含 s.substring(j, i), 那么 dp[i] 就可以被设置为 true,表示字符串 s 的前 i 个字符可以被拼接而成。

  • 2、初始化数组dp,长度为s.length() + 1,全部初始化为false。

  • 3、设置dp[0]为true,表示空字符串可以被拆分。

  • 4、使用两层循环遍历字符串s的每个字符,外层循环遍历从1到s.length(),内层循环遍历从0到i,判断从0到j的子串是否可以被拆分,并且判断从j到i的子串是否在wordDict中,如果满足条件,则将dp[i]设置为true。

  • 5、最终返回dp[s.length()]即可。

Java实现

public class WordBreak {
    public boolean wordBreak(String s, List<String> wordDict) {
        Set<String> wordSet = new HashSet<>(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] && wordSet.contains(s.substring(j, i))) {
                    dp[i] = true;
                    break;
                }
            }
        }
        
        return dp[n];
    }

    public static void main(String[] args) {
        WordBreak wb = new WordBreak();
        String s = "leetcode";
        List<String> wordDict = Collections.unmodifiableList(
                Arrays.asList("leet", "code"));
        System.out.println("Can be broken: " + wb.wordBreak(s, wordDict));
        // Output: true ("leetcode" can be broken into "leet" and "code")
    }
}

时间空间复杂度

  • 时间复杂度:外层循环遍历了s.length()次,内层循环遍历了字符串s的每个字符,时间复杂度为O(n^2),其中n为字符串s的长度。

  • 空间复杂度:使用了长度为s.length() + 1的数组dp和一个哈希集合wordSet,空间复杂度为O(n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值