Blage's Coding Blage's Coding
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
  • 数组

  • 链表

  • 字符串

  • 二叉树

  • 动态规划

    • 5.最长回文子串
    • 72.编辑距离
    • 300.最长递增子序列
    • 1143.最长公共子序列
    • 239.滑动窗口最大值
    • 64.最小路径和
    • 718.最长重复子数组
    • 221.最大正方形
    • 198.打家劫舍
    • 152.乘积最大子数组
    • 1079.活字印刷
    • 139. 单词拆分
      • 1.DFS+剪枝
      • 2.动态规划+背包问题
    • 6394. 字符串中的额外字符
    • 10. 正则表达式匹配
    • 1130. 叶值的最小代价生成树
    • 96. 不同的二叉搜索树
    • 279. 完全平方数
    • 416. 分割等和子集
    • 309. 最佳买卖股票时机含冷冻期
    • 312. 戳气球
    • 53. 最大子数组和
    • 1262. 可被三整除的最大和
    • 1186. 删除一次得到子数组最大和
    • 6912. 构造最长非递减子数组
    • 1911. 最大子序列交替和
    • 834. 树中距离之和
    • 343. 整数拆分
    • 123. 买卖股票的最佳时机 III
    • 115. 不同的子序列
    • 516. 最长回文子序列
    • 132. 分割回文串 II
    • 673. 最长递增子序列的个数
    • 2930. 重新排列后包含指定子字符串的字符串数目
    • 2646. 最小化旅行的价格总和
    • 剑指offer42
    • 剑指offer60
    • 剑指 Offer 49. 丑数
    • 背包问题

  • 深搜回溯

  • 数学贪心

  • 堆栈队列

  • 前缀和

  • 算法设计

  • 位运算

  • WA

  • 算法
  • 动态规划
phan
2023-05-27
目录

139. 单词拆分

# 139. 单词拆分 (opens new window)

# 1.DFS+剪枝

解题思路:DFS搜索每个前缀字符串是否能够被模式串匹配。需要注意如果不剪枝的话搜索空过大,从而导致超时,因此需要剪枝。

首先明白什么情况下需要剪枝,假设当前需要匹配的字符串为“aabbccc”,而模式串为["aa","bb","aabb"],当前字符串dfs搜索发现aabb子串可以进行匹配,但是这里有两种方式,如果不进行剪枝的话使用“aa” "bb"匹配和使用"aabb"两种匹配方式都会被搜索到,而题目最终只需要判断字符串能否匹配,并需要给出所有匹配的方案数。因此对于从开始索引0到当前索引下标i的子串,在搜索时需要保证它只会被匹配一次。

剪枝:做法是开辟一个list容器空间,保存已经匹配的子串下标i。每次搜索当前位置时,除了需要判断以当前索引结尾的子串是否可以匹配之外,还需要判断当前位置是否被匹配过。

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        List<Integer> list=new ArrayList<>();
        return dfs(s,wordDict,list,0);
    }
    public boolean dfs(String s,List<String> wordDict,List<Integer> list,int index){
          for(int i=index;i<s.length();i++){
              if(wordDict.contains(s.substring(index,i+1))&&!list.contains(i)){
                  if(i==s.length()-1) return true;
                  list.add(i);
                  if(dfs(s,wordDict,list,i+1)) return true;
              }
          }
          return false;  
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 2.动态规划+背包问题

上一种做法List列表就可以看作是一个动态规划数组。dp[i]表示以i结尾的子串是否能够匹配。遍历时采用两层嵌套循环,其中外层循环i控制子串的右边界,内层循环遍历子串的每一个位置j。也就是说要判断【0,i】能够匹配,需要枚举j判断【0,j】与【j,i】能否同时匹配。

状态转移公式为:dp[i]=dp[j]&&wordDict.contains(s.substring(j,i+1))

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        boolean[] dp=new boolean[s.length()];
        for(int i=0;i<s.length();i++){
            dp[i]=wordDict.contains(s.substring(0,i+1));
            for(int j=0;j<i;j++){
                 dp[i]=dp[i]||(dp[j]&&wordDict.contains(s.substring(j+1,i+1)));
            }
        }
        return dp[s.length()-1];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
编辑 (opens new window)
#Leetcode#动态规划
上次更新: 2023/12/15, 15:49:57
1079.活字印刷
6394. 字符串中的额外字符

← 1079.活字印刷 6394. 字符串中的额外字符→

Theme by Vdoing | Copyright © 2023-2024 blageCoder
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式