题意:

image.png

解题思路:

  1. 思路:时间复杂度:O(n2)
  2. 1. 初始化 dp=[False,~,False],长度为 n+1n 为字符串长度,dp[i]表示s的前i位是否可以用wordDict中的单词表示。
  3. 2. 初始化 dp[0]=True,空字符可以被表示。
  4. 3. 遍历字符串的所有子串,遍历开始索引 i,遍历区间 [1, n):
  5. * 遍历结束索引j,遍历区间 [0~i):
  6. dp[j]=True s[i,⋯,j) wordlist中:dp[i] = True
  7. 解释:dp[j]=True说明 s 的前 j 位可以用 wordDict表示,则 s[i,⋯,j) 出现在 wordDict 中,说明 s 的前 i 位可以表示。
  8. 4. 返回 dp[n]
  9. 首先,s[0:4]=='leet' wordDict内的单词,所以dp[4]=True
  10. 继续以0为起点,4以后的索引为终点的单词都不在字典内,选择忽略。
  11. 'leetc','leetco','leetcod','leetcode'都不在字典内,忽略不管。
  12. 第二步,因为之前设置了DP[4]=True,所以迭代至4为起点
  13. 查看后面的单词是否在字典内。发现s[4:8]=='code' 在字典内,
  14. 所以设置DP[8]为True,至此循环结束。

PHP代码实现:

  1. class Solution {
  2. /**
  3. * @param String $s
  4. * @param String[] $wordDict
  5. * @return Boolean
  6. */
  7. function wordBreak($s, $wordDict) {
  8. $dp = [0 => true] + array_fill(1, strlen($s), false);
  9. for ($i = 0; $i < strlen($s); $i++) {
  10. for ($j = 1; $j <= strlen($s); $j++) {
  11. if ($dp[$i] && in_array(substr($s, $i, $j - $i), $wordDict)) {
  12. $dp[$j] = true;
  13. }
  14. }
  15. }
  16. return end($dp);
  17. }
  18. function wordBreak2($s, $wordDict) {
  19. $n = strlen($s);
  20. $dp = array_fill(0, $n + 1, false);
  21. $dp[0] = true;
  22. for ($i = 1; $i <= $n; $i++) {
  23. for ($j = 0; $j < $i; $j++) {
  24. $word = substr($s, $j, $i - $j);
  25. if ($dp[$j] && in_array($word, $wordDict)){
  26. $dp[$i] = true;
  27. break;
  28. }
  29. }
  30. }
  31. return $dp[$n];
  32. }
  33. function wordBreak1($s, $wordDict) {
  34. $memo = [];
  35. return $this->helper($s, $wordDict, 0, $memo);
  36. }
  37. function helper($s, $wordDict, $start, &$memo) {
  38. if ($start == strlen($s)) return true;
  39. if (isset($memo[$start])) return $memo[$start];
  40. for ($end = $start + 1; $end <= strlen($s); ++$end) {
  41. if (in_array(substr($s, $start, $end - $start), $wordDict) && $this->helper($s, $wordDict, $end, $memo)) {
  42. $memo[$start] = true;
  43. return true;
  44. }
  45. }
  46. $memo[$start] = false;
  47. return false;
  48. }
  49. }

GO代码实现:

  1. func wordBreak(s string, wordDict []string) bool {
  2. wordDictSet := make(map[string]bool)
  3. for _, v := range wordDict {
  4. wordDictSet[v] = true
  5. }
  6. dp := make([]bool, len(s) + 1)
  7. dp[0] = true
  8. for i := 1; i <= len(s); i++ {
  9. for j := 0; j<i; j++ {
  10. if dp[j] && wordDictSet[s[j:i]] {
  11. dp[i] = true
  12. break
  13. }
  14. }
  15. }
  16. return dp[len(s)]
  17. }