【DP】LeetCode 139. 单词拆分

发布时间 2023-04-18 16:16:53作者: Frodo1124

题目链接

139. 单词拆分

思路

分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律

在数组的动态规划问题中,一般 dp[i] 都是表示以 nums[i] 为结尾的状态;dp[i][j] 分别表示 以 nums1[i]nums2[j] 为结尾的状态,以此类推

字符串也是个数组,是字符数组

表示状态

首先构思一下我们需要存储的信息,以此来确定 dp 数组的维数:

  1. 当前遍历的下标
  2. s[i] 为结尾的状态

因为只用存储两个信息,所以只需要使用一维数组 dp[i] 来表示以 s[i] 为结尾的状态,这个状态就是 s[0:i] 能否使用字典中字符串表示

找状态转移方程

dp[i] 取值取决于两点:

  1. s[0 : j - 1] 是否能分解,即 dp[j] 是否是true
  2. s[j : i - 1] 是否能分解为字典里的字符串

边界处理

很明显 dp[0] = true

代码

dp数组版

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        // dp[i] 表示以第 i 个字符为结尾是否符合条件
        Set<String> set = new HashSet<>(wordDict);
        boolean[] dp = new boolean[s.length() + 1];

        // dp[i]取值取决于两点:
        // 1.s[0 : j - 1]是否能分解,即dp[j]是否是true
        // 2.s[j : i - 1]是否能分解为字典里的字符串
        dp[0] = true;
        for(int i = 1; i <= s.length(); i++){
            for(int j = i - 1; j >= 0; j--){
                String subString = s.substring(j, i);
                if(dp[j] && set.contains(subString)){
                    dp[i] = true;
                    break;
                }
            }
        }

        return dp[s.length()];
    }
}