Word Splitting-Dynamic Programming-LeetCode

Posted by svenski on Thu, 10 Oct 2019 19:09:55 +0200

Problem description

Given a non-empty string s and a dictionary word Dict containing a list of non-empty words, it is determined whether s can be split into one or more words in the dictionary by spaces.

Explain:
The words in the dictionary can be reused when splitting.
You can assume that there are no repetitive words in the dictionary.

Example 1:
Input: s = leetcode, wordDict = ["leet", "code"]
Output: true
Interpretation: Return true because "leet code" can be split into "leet code".

Example 2:
Input: s = applepenapple, wordDict = ["apple", "pen"]
Output: true
Interpretation: Return true because "apple pen apple" can be split into "apple pen apple".
Note that you can reuse the words in the dictionary.

Example 3:
Input: s = catsandog, wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false

Solving problems

code implementation

package solution;

import java.util.*;

class Solution {
    List<List<String>> lists;

    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        list.add("cats");
        list.add("dog");
        list.add("sand");
        list.add("and");
        list.add("cat");
        new Solution().wordBreak("catsandog",list);
    }
    public boolean wordBreak(String s, List<String> wordDict) {
        if (s == null || s.length() == 0) {
            return true;
        }
        Set<String> set = new HashSet<>(wordDict);
        int maxLen = getMaxLen(set);
        // A word of length n has a total of n + 1 tangent points
        boolean[] canSegment = new boolean[s.length() + 1];
        canSegment[0] = true;

        for (int i = 1; i < canSegment.length; i ++) {
            for (int j = 1; j <= maxLen && j <= i; j ++) {
                // i - j denotes j positions from i to forward
                String str = s.substring(i - j, i);
                //If the word qualifies and the first letter of the word corresponds to the canSegment, it is already true.
                if (set.contains(str) && canSegment[i - j]) {
                    canSegment[i] = true;
                    break;
                }
            }
        }
        return canSegment[canSegment.length - 1];
    }
    private int getMaxLen(Set<String> set) {
        int maxLen = 0;
        for (String word : set) {
            maxLen = Math.max(maxLen, word.length());
        }
        return maxLen;
    }
}

Word splitting 2

Given a non-empty string s and a dictionary word Dict containing a list of non-empty words, add spaces to the string to construct a sentence so that all the words in the sentence are in the dictionary. Return all these possible sentences.

Explain:

The words in the dictionary can be reused when separating.
You can assume that there are no repetitive words in the dictionary.

Example 1:

input:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
//Output:
[
  "cats and dog",
  "cat sand dog"
]

Example 2:

Input:
s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
Output:
[
  "pine apple pen apple",
  "pineapple pen apple",
  "pine applepen apple"
]
Explanation: Note that you can reuse the words in the dictionary.

Example 3:

input:
s = "catsandog"
wordDict = ["cats", "dog", "sand", "and", "cat"]
//Output:
[]
package solution;

import java.util.ArrayList;
import java.util.List;

public class Solution4 {
    public static void main(String[] args) {
        String s="catsanddog";
        List<String> wordDict = new ArrayList<>();
        wordDict.add("cat");
        wordDict.add("cats");
        wordDict.add("dog");
        wordDict.add("sand");
        wordDict.add("and");
        new Solution4().wordBreak(s,wordDict);
        System.out.println(s);
    }
    private List<String> result;
    public List<String> wordBreak(String s, List<String> wordDict) {
        if (wordDict.size()<1){
            return new ArrayList<>();
        }
        
        result=new ArrayList<>();
        //Judge first whether it can be split
        if(!confirm(s,wordDict)){
            return result;
        }
        //Each traversal of split markup
        boolean[] flag=new boolean[s.length()];
        //If it can be split
        find(s,0,flag,wordDict);
        return result;
    }
    private boolean confirm(String s,List<String> words){
        boolean[] flag=new boolean[s.length()+1];
        flag[0]=true;
        //Find the longest word length in the dictionary
        int maxLen=findMax(words);
        for(int i=1;i<flag.length;i++){
            //To see if the words before i are satisfied, the maximum length of the word is maxLen
            for(int j=1;j<=maxLen&&j<=i;j++) {
                String str=s.substring(i-j,i);
                //The first letter of str corresponds to a mark that is true, and str is in the dictionary.
                if(flag[i-j]&&words.contains(str)){
                    
                    flag[i]=true;
                }
            }
        }
        return flag[flag.length-1];
    }

    private int findMax(List<String> words) {
        int max=words.get(0).length();
        for(String s:words){
            if(max<s.length()){
                max=s.length();
            }
        }
        return max;
    }

    private void find(String s,int index,boolean[] flag,List<String> words){
        //After marking up, the segmentation begins.
        if(index==s.length()){
            StringBuilder sb=new StringBuilder();
            int begin=0;//Segmentation starting point
            for(int last=0;last<s.length();last++){
                if(flag[last]){
                    sb.append(s.substring(begin,last+1)+" ");
                    begin=last+1;
                }
            }
            sb.deleteCharAt(sb.length()-1);
            result.add(sb.toString());
        }

        for(int i=index;i<s.length();i++){
            //Mark qualified words from index
            if(words.contains(s.substring(index,i+1))){
                flag[i]=true;
                //Satisfies the condition, then marks from i+1
                find(s,i+1,flag,words);
                //After a round of traversal, all markers are cleared
                flag[i]=false;
            }
        }
    }

}

Topics: Java