[Dynamic programming] Split words

Today, I will continue to study dynamic programming in depth and analyze the case of "splitting words and sentences". The key and difficulty of solving the problem mainly lies in the analysis of the problem state.

Bull link

Question: Given a string s and a set of words dict, determine whether s can be split into a word sequence with spaces such that all words in the word sequence are words in the dict (sequence can contain one or more words).

For example:
given s="nowcode";
dict=["now", "code"].
Returns true because "nowcode" can be split into "now code".

If you have not studied dynamic programming ideas, you are somewhat at a loss when faced with such a problem. You don't know how to start a seemingly simple problem. You may want to use a violent solution to divide nowcode into n and owcode to see if they are all in the dictionary dict. appears in, if it doesn't work, try to divide it into no and wcode, until all the divisions of this string may be tried again, if it doesn't work, it means that the string cannot be split, and vice versa.

The written idea is quite good, but if you really want to implement it in this problem, it will be a big deal. It is not necessary. You can solve this problem with simple code using dynamic programming ideas.

insert image description here
insert image description here

If you want to know the state of F(1), F(2),...,F(6), the actual method and the method of finding F(7) are actually exactly the same. These states are to solve the F(7) state. The state of the small problems that need to be known in the process, the so-called small problems have a relative relationship between small problems and large problems, progressively, and finally get the desired result

Analyze the problem from four angles:

  1. State definition F(i): Whether the first i characters of the string can be found in the dictionary after being split The state is true, otherwise false
  2. Definition of transition equation between states: F(i) = j < i && F(j) && [j + 1,i]
  3. State initialization: F(0) = true
  4. Return result: F(s.length())

Code display:

import java.util.*;
public class Solution {
    
    
    public boolean wordBreak(String s, Set<String> dict) {
    
    
        boolean[] canBreak = new boolean[s.length() + 1]; //用来记录前i个状态
        canBreak[0] = true;  //初始状态
        for(int i = 1;i <= s.length();i ++) {
    
    
            for(int j = 0; j < i;j ++) {
    
    
                //需要注意索引是从0开始,并且substring方法的下标范围前开后闭的特点
                canBreak[i] = canBreak[j] && dict.contains(s.substring(j,i));
                //在循环过程中如果该状态为true,说明前i个字符是可以被分割后在词典中找到的,可以直接跳出本轮循环,去求下一个状态的值
                if(canBreak[i] == true) {
    
    
                    break;
                }
            }
        }
        //返回结果
        return canBreak[s.length()];
    }
}

Finish!

Guess you like

Origin blog.csdn.net/weixin_46103589/article/details/121870295