LeetCode 139 单词拆分

题目描述

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

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

思路

这是一个完全背包问题,并且是排列问题,要注意先遍历背包(字符串长度)再遍历物品(word),因为一个word可能会需要使用多次,如果先遍历word的话,那么第一次遍历完之后后面就选不到它了。

具体步骤

假设输入字符串为s

1 确定dp数组的含义

dp[j]表示从字符串首字母开始,长度为j的字符串(即s[0~j-1])是否能由wordDict中的单词拼接而成,是为true,否为false

2 确定状态转移方程

dp[j] = word.equals(s.substring(j - word.length, j)) && dp[j - word.length()]

就是如果当前选择的word能构成s[0~j-1]的屁股,并且s除去这个屁股的前半部分可以由wordDict中的字符串构成,则dp[j]=true

3 初始状态

因为整个判断的过程是先判断屁股,然后判断前面,所以最初始的状态就是屁股就等于s的全部,则s的前半部分是个空串,由dp[0]表示,由于后面的全部都是由前面的推导出来的,所以dp[0]应该初始化为0。

4 遍历顺序

外层从前往后遍历dp数组的下标,内层遍历wordDict

代码

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        int len = s.length();
        boolean[] dp = new boolean[len + 1];
        dp[0] = true;
        //dp[j] = word.equals(s.substring(j - word.length, j)) && dp[j - word.length()]
        
        for (int j = 1; j <= len; j++) {
            for (String word : wordDict) {
                if (word.length() > j) {
                    continue;
                }
                if (!word.equals(s.substring(j - word.length(), j))) {
                    continue;
                }
                if (dp[j - word.length()]) {
                    dp[j] = true;
                    break;
                }
            }
        }
        
        return dp[len];
    }
}
posted @   wutao666  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示