leetCode 139. Word split + complete backpack + number of permutations

You are given a string  s and a list of strings  wordDict as a dictionary. Please judge whether it can be spliced ​​using words that appear in the dictionary  s .

Note: It is not required to use all the words that appear in the dictionary, and words in the dictionary can be used repeatedly.

Example 1:

Input: s = "leetcode", wordDict = ["leet", "code"]
 Output: true
 Explanation: Return true because "leetcode" can be spliced ​​into "leet" and "code".

Example 2:

Input: s = "applepenapple", wordDict = ["apple", "pen"]
 Output: true
 Explanation: Return true because "applepenapple" can be spliced ​​into "apple" "pen" "apple".
     Note that you can reuse words from the dictionary.

Example 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

>>Think and analyze

This question can be violently searched using the backtracking algorithm , which is to violently search for various segmentation situations, and then determine whether it appears in this dictionary. But in this article we mainly use a complete backpack to solve the problem.

First of all, to analyze this question, let us split the word and ask whether it appears in the wordDict dictionary . Then can we think about it the other way around? In fact, there are these words in this dictionary , and ask us if we can form this string s , right? Then this string s can be understood as a container or a backpack , and these words are an item . The question turned into whether these items can exactly fill the backpack. At this time, I found that it was a bit like a backpack-type problem. Each item here can be used multiple times , such as this apple, so this is a complete backpack type problem. In this question, these items can be used unlimited times. Ask us if we can fill this backpack and find the number of permutations.

s = applepenapple,wordDict = ["apple","pen"]

           ↓     ↓     ↓                                ↓         ↓

   ->    1     2     1                                1         2

The string s is a sequence like 1 2 1, so what we are looking for is the number of permutations. We need to traverse the backpack first, and then traverse the items.

  • ① Each item can be used multiple times (complete backpack problem)
  • ② Since what is sought is the number of permutations, determine the order of traversal

>>Five Steps of Dynamic Rules

1. Determine the meaning of the dp array and subscripts

dp[i]: If the string length is i, dp[i] is true, which means it can be split into one or more words that appear in the dictionary.

2. Determine the recursion formula

If it is determined that dp[j] is true, and the substring of the interval [j,i] appears in the dictionary, then dp[i] must be true. (j<i)

So the recurrence formula is

if([j,i] 这个区间的子串出现在字典里 && dp[j] == true) 
    dp[i] = true

 

3.dp array initialization

  • It can be seen from the recursion formula that the state of dp[i] depends on whether dp[j] is true. Then dp[0] is the basis of recursion. dp[0] must be initialized to true, otherwise all the subsequent recursions will be false.
  • dp[i] with a non-0 subscript is initialized to false. As long as it is not overwritten, it cannot be split into one or more words that appear in the dictionary.

Thinking: Does dp[0] make sense?

dp[0] means that if the string is empty, it means it appears in the dictionary, but the question says "given a non-empty string s", so i is 0 in the test data, then dp[0 ] The initial value is true just to derive the formula.

4. Determine the traversal order

This question must first traverse the backpack and then traverse the items. Here’s why:

In full backpack:

  • If you want to find the number of combinations, the outer for loop traverses the items, and the inner for loop traverses the backpack.
  • If you want to find the number of permutations, the outer for loop traverses the backpack, and the inner for loop traverses the items.

In s = "applepenapple", wordDict = ["apple", "pen"], "apple" and "pen" are items, so the combination of items must be "apple" + "pen" + "apple" to form" applepenapple". "apple" + "apple" + "pen" or "pen" + "apple" + "apple" are not allowed, so the order between items is emphasized.

5. Recommend dp[i] as an example

s = "leetcode",wordDict = ["leet","coded"], the dp status is as shown in the figure:

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
        vector<bool> dp(s.size() + 1, false);
        dp[0] = true;
        for (int i = 1; i <= s.size(); i++) {   // 遍历背包
            for (int j = 0; j < i; j++) {       // 遍历物品
                string word = s.substr(j, i - j); //substr(起始位置,截取的个数)
                if (wordSet.find(word) != wordSet.end() && dp[j]) {
                    dp[i] = true;
                }
            }
        }
        return dp[s.size()];
    }
};
  • Time complexity :O(n^3), becausesubstrreturns a copy of the substring withO(n)(n here is the length of the substring)
  • Space complexity :O(n)

Reference and recommended articles and videos:

Code Random Record (programmercarl.com)

Dynamic programming: complete backpack, how to fill your backpack? | LeetCode: 139. Word Splitting_bilibili_bilibili

Class screenshots from Code Caprice:

 

Guess you like

Origin blog.csdn.net/weixin_41987016/article/details/133420672