上午把docker基础学完了。下午来了闲的无聊,做一题先。
1、题目描述
2、逻辑分析
这个问题是一个典型的动态规划问题,我们可以使用一个布尔数组 dp
来记录字符串 s
的前缀是否可以被拆分成字典中的单词。具体地,dp[i]
表示字符串 s
的前 i
个字符(即 s.substring(0, i)
)是否可以被拆分成字典中的单词。
算法的基本思路是,从字符串 s
的第一个字符开始,逐步向后检查每个位置。对于每个位置 i
,我们再次遍历从位置 0
到 i-1
的所有位置 j
,并检查子串 s.substring(j, i)
是否在字典中。如果 s.substring(j, i)
在字典中,并且 dp[j] 为 true
(即 s
的前 j
个字符可以被拆分),那么我们就可以将 dp[i]
设置为 true
。
3、代码演示
public boolean wordBreak(String s, List<String> wordDict) {
// 将字典 wordDict 转换为 HashSet,以便快速查找
Set<String> wordDictSet = new HashSet<>(wordDict);
// 创建一个布尔数组 dp,dp[i] 表示 s 的前 i 个字符是否可以被拆分
boolean[] dp = new boolean[s.length() + 1];
// 初始化 dp[0] 为 true,因为空字符串总是可以被拆分的
dp[0] = true;
// 从第一个字符开始遍历到字符串末尾
for(int i = 1; i <= s.length(); i++){
// 从第 0 个字符到当前字符的前一个字符进行遍历(包含)
for(int j = 0; j < i; j++){
// 如果 s 的前 j 个字符可以被拆分(即 dp[j] 为 true)
// 并且 s 的从第 j 个字符到当前字符的子串在字典中
//(即 wordDictSet.contains(s.substring(j, i)) 为 true)
if(dp[j] && wordDictSet.contains(s.substring(j, i))){
// 那么 s 的前 i 个字符也可以被拆分,设置 dp[i] 为 true
dp[i] = true;
// 因为已经找到了一个拆分方式,所以可以提前跳出内层循环
break;
}
}
}
// 返回 s 是否可以被完全拆分,即 dp[s.length()] 是否为 true
return dp[s.length()];
}
以字符串 s = “leetcode
” 和字典 wordDict = ["leet", "code"]
为例来解释这段代码。
- 首先,我们初始化一个长度为
9
的布尔数组dp
,所有元素都初始化为false
,除了dp[0]
,它表示空字符串,所以初始化为
true
。 - 然后,我们开始遍历字符串
"leetcode"
的每个字符,同时对于每个字符,我们都会遍历从当前字符到字符串末尾的每个子字符串。 - 当
i = 0
时,我们检查子字符串"l", "le", "lee", "leet", "leetc", "leetco","leetcod", "leetcode"
。当我们检查到"leet"
时,我们发现"leet"
在字典中,而且dp[0]
是true
,所以我们将dp[4]
设置为true
。 - 当
i = 1
时,我们检查子字符串"e", "ee", "eet", "eetc", "eetco", "eetcod", "eetcode"
。但是因为dp[1]
是false
,所以我们不会更新任何dp[j]
。 - 当
i = 2
和i = 3
时,同样因为dp[2]
和dp[3]
都是false
,所以我们也不会更新任何dp[j]
。 - 当
i = 4
时,我们检查子字符串"c", "co", "cod", "code"
。当我们检查到"code"
时,我们发现"code"
在字典中,而且dp[4]
是true
,所以我们将dp[8]
设置为true
。 - 最后,我们返回
dp[8]
,也就是true
,表示字符串"leetcode"
可以被拆分为字典中的单词。
4、复杂度分析
- 时间复杂度: O ( n 2 ) O(n^{2}) O(n2)。我们一共有 O ( n ) O(n) O(n) 个状态需要计算,每次计算需要枚举 O ( n ) O(n) O(n)个分割点,哈希表判断一个字符串是否出现在给定的字符串列表需要 O ( n ) O(n) O(n)的时间,因此总时间复杂度为 O ( n 2 ) O(n^{2}) O(n2)。
- 空间复杂度: O ( n ) O(n) O(n),哈希集合和dp布尔数组需要存放元素。
over,拜拜!