力扣139.单词拆分(java)

  题目描述

难度:中等

示例

思路

动态规划

动态规划适合解决具有重叠子问题和最优子结构性质的问题。在这个问题中,判断一个字符串能否被分割成由给定字典中的单词构成,就涉及到这种子问题的重复性和最优子结构,动态规划法通过存储中间结果并递推求解,实现了高效的字符串分割判断功能。

解题方法

1.首先将 wordDict 转换为 HashSet,这样可以快速查找字符串是否在 wordDict 中。
创建存储子解的boolean数组dp,设dp[0]为TRUE,表示空字符串可以被拆分(这是动态规划中的初始条件)

2.创建两个for循环进行判断;
外层循环遍历字符串 s 的每一个位置 i,从 1 到 s.length();
内层循环遍历位置 i 前面的每一个位置 j,j 从 0 到 i-1;
如果 dp[j] 为 true,说明 s 的前 j 个字符可以被成功拆分成 wordDict 中的单词,且从 j 到 i 的子串 s.substring(j, i) 存在于 wordDict 中,那么 dp[i] 就设为 true 

3.遍历完成后返回结果dp[s.length()]

注意:dp长度为s.length()+1,因为dp[0]为空数组

(s.substring(j,i))为左闭右开

java代码

力扣官方题解+个人注解:

public class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        Set<String> wordDictSet = new HashSet(wordDict);
        boolean[]dp = new boolean[s.length()+1];
        //初始化 dp[0] 为 true,表示空字符串可以被拆分
        dp[0] = true;
        for(int i = 1; i<= s.length(); i++) {
            for(int j = 0; j<i; j++) {
                
                if(dp[j] && wordDictSet.contains(s.substring(j,i))){
                    dp[i]=true;
                    //使用 break 可以减少不必要的循环
                    break;
                }
            }
        }
        return dp[s.length()];
    }
}

复杂度分析:

时间复杂度

外循环会执行n次,n为字符串s长度,内循环则依赖于外循环的i值,因此时间复杂度为O(n^2)。

空间复杂度

创建了布尔数组和哈希表,它们都需要O(n)的空间,因此空间复杂度为O(n)。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值