Leetcode 单词拆分

以下是LeetCode问题139"单词拆分"(Word Break)的Java解法,使用了动态规划(Dynamic Programming, DP)来解决这个问题:

java 复制代码
import java.util.List;
import java.util.Set;
import java.util.HashSet;

public class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        // 将wordDict转化为一个Set,以加快查找速度
        Set<String> wordSet = new HashSet<>(wordDict);
        // 创建一个DP数组,dp[i]表示字符串s的前i个字符是否可以由字典中的单词拼接而成
        boolean[] dp = new boolean[s.length() + 1];
        // 空字符串可以被认为是可拼接的
        dp[0] = true;
        
        // 动态规划填充dp数组
        for (int i = 1; i <= s.length(); i++) {
            for (int j = 0; j < i; j++) {
                // 如果s的前j个字符可拼接,且[j, i)这部分字符在字典中
                if (dp[j] && wordSet.contains(s.substring(j, i))) {
                    dp[i] = true;
                    break;  // 找到一个可拼接方案后就可以跳出当前循环
                }
            }
        }
        // dp[s.length()]就是答案,表示整个字符串s是否可拼接
        return dp[s.length()];
    }
}

解决思路:

  1. 使用动态规划

    • 定义一个布尔数组 dp[],其中 dp[i] 表示从字符串的开头到索引 i-1 的子字符串是否可以用字典中的单词拆分出来。
    • dp[0] 表示空字符串,因此我们初始化 dp[0] = true
  2. 递推关系

    • 对于每个 i,我们检查 j0i 的所有位置,如果 dp[j]true 并且 s[j:i] 存在于 wordDict 中,那么我们设置 dp[i] = true,并跳出内部循环。
  3. 时间复杂度

    • 由于每个子串的生成和查找都可能花费 O(n) 的时间,总体时间复杂度为 O(n^2),其中 n 是字符串 s 的长度。

java solution

java 复制代码
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
      //将List<String> wordDict转化为HashSet, wordDict中的string作为hashset中的key
        Set<String> wordSet = new HashSet<>(wordDict);
        //dp[i] 表示s的前i个字符(下标0~i-1)构成的子串是否可以成功拆分
        //这里之所以需要创建s.length() + 1个数组单元是因为s.length() + 1个数组单元的下标范围是[0,s.length()]
        boolean[] dp = new boolean[s.length() + 1];
        dp[0] = true;


        //将子串(0,i)拆分为2部分,(0,j)和(j,i), 下标都是左闭右开。
        // 如果(0,j)这一部分可以成功拆分并且另一部分(j,i)在字典中,说明子串(0,i)是可以成功被拆分的
        for(int i = 0; i <= s.length(); ++i) {
            for(int j = 0; j < i; ++j) { 
                if(dp[j] == true && wordSet.contains(s.substring(j, i))) {
                    dp[i] = true;
                    break; // break 只能跳出当前的 内部 for 循环
                }
            }
        }
        return dp[s.length()];
    }
}
相关推荐
StickToForever3 小时前
第4章 信息系统架构(五)
经验分享·笔记·学习·职场和发展
计算机小白一个5 小时前
蓝桥杯 Java B 组之设计 LRU 缓存
java·算法·蓝桥杯
万事可爱^6 小时前
HDBSCAN:密度自适应的层次聚类算法解析与实践
算法·机器学习·数据挖掘·聚类·hdbscan
欧了1117 小时前
洛谷P9240 [蓝桥杯 2023 省 B] 冶炼金属
职场和发展·蓝桥杯·洛谷·蓝桥杯大学b组c语言
大数据追光猿8 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!8 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉8 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生8 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴8 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing8 小时前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode