【刷题1】LeetCode 139. 单词拆分 java题解

人生的大起大落就在一瞬间:吃完饭回来看到粉丝+1并为此开心,过了几分钟再看就没有了。
另外下午真的是诸事不宜啥也不想学的时间段。(这题直接先看题解吧

1.题目

在这里插入图片描述

2.分析

转移方程:
dp[i]表示字符串的前i个字符能否成功拆分,需要枚举s[0…i-1]中的分割点j,看s[0…j-1]和s[j…i-1]能否成功拆分。而s[0…j-1]正是dp[j]。
在这里插入图片描述

边界条件:
dp[0]=true,表示空串且合法

check的实现:检查一个字符串是否出现在给定的字符串列表里一般可以考虑哈希表来快速判断。

剪枝优化:
剪枝,枚举分割点的时候倒着枚举,如果分割点 j 到 i -1的长度已经大于字典列表里最长的单词的长度,那么就结束枚举。

3.代码

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

        //找到set中最长单词的长度
        int maxw=0;
        for(String c:set){
            maxw=Math.max(maxw,c.length());
        }

        for(int i=1;i<=len;i++){//从0位置开始,长度为i的字符串
            for(int j=i-1;j>=0&&j>=i-maxw;j--){// i-1-j+1=i-j是右边部分的长度,如果超出最长单词长度就不用看了
            //dp[j]:[0,j-1]
            //substring(j,i): [j,i-1]
                if(dp[j]&&set.contains(s.substring(j,i))){
                    dp[i]=true;//说明长度为i成功了,继续验证下一个长度,回到外层循环
                    break;
                }
            }
        }
        return dp[len];
    }
}

4.复杂度

时间复杂度:O(n²) ,其中 n 为字符串 s 的长度。我们一共有O(n)个状态需要计算,每次计算需要枚举O(n)个分割点,哈希表判断一个字符串是否出现在给定的字符串列表需要O(1)的时间,因此总时间复杂度为 O(n²)。

空间复杂度:O(n),其中 n为字符串 s 的长度。我们需要O(n) 的空间存放dp 值以及哈希表亦需要 O(n)的空间复杂度,因此总空间复杂度为 O(n)。

5.结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值