天天看点

leetcode word-break-ii(Java)leetcode题目题目描述思路代码

leetcode题目

word-break-ii
           

题目描述

* Given a string s and a dictionary of words dict, 
 * add spaces in s to construct a sentence where each word is a valid dictionary word.
 * Return all such possible sentences.
 * For example, given
 * s ="catsanddog",
 * dict =["cat", "cats", "and", "sand", "dog"].
 * A solution is["cats and dog", "cat sand dog"].
           

思路

* 1、将字符串切割为两部分左边s1和右边s2,如果s1包含在字典中,则递归计算s2切割生成的字符串集合,并将s1和s2返回的结果并和。
 * 2、 如果s2可能无法切割,我们让其返回一个空的ArrayList。
 * 3、 如果s为空串是我们规定返回包含一个“”的ArrayList.
 * 4、仅仅递归会超时,我们用一个map记录字符串对应的结果,不重复判断。
           

代码

package com.my.test.leco.dyncplanning;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 题目:
 * word-break-ii
 * 
 * 题目描述:
 * Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
 * Return all such possible sentences.
 * For example, given
 * s ="catsanddog",
 * dict =["cat", "cats", "and", "sand", "dog"].
 * A solution is["cats and dog", "cat sand dog"].
 * 
 */
public class WordBreakII
{
    /**
     * 思路:
     * 1、递归求解(牛客网leetcode可通过(限制了元素的输出顺序))
     */
    public ArrayList<String> wordBreak1(String s, Set<String> dict) {
        ArrayList<String> list = new ArrayList<>();
        dfs1(s, s.length(), "", dict,list);
        return list;
    }
 
    private void dfs1(String s, int index, String str, Set<String> dict, List<String> list) {
        if (index <= 0) {
            if (str.length() > 0) {
                list.add(str.substring(0, str.length() - 1));
            }
        }
        for (int i = index; i >= 0; i--) {
            if (dict.contains(s.substring(i, index))) {
                dfs1(s, i, s.substring(i, index) + " " + str, dict, list);
            }
        }
    }
    
    /**
     * 牛客网限制了输出顺序,不能通过(吐槽下),该解法leetcode网站上可通过
     * 
     * 思路:
     * 1、将字符串切割为两部分左边s1和右边s2,如果s1包含在字典中,则递归计算s2切割生成的字符串集合,并将s1和s2返回的结果并和。
     * 2、 如果s2可能无法切割,我们让其返回一个空的ArrayList。
     * 3、 如果s为空串是我们规定返回包含一个“”的ArrayList.
     * 4、仅仅递归会超时,我们用一个map记录字符串对应的结果,不重复判断。
     */
    public List<String> wordBreak(String s, Set<String> dict) {
        HashMap<String, List<String>> map = new HashMap<String, List<String>>();
        ArrayList<String> ret = dfs(s, dict, map);
        return ret;
    }
     
    private ArrayList<String> dfs(String s, Set<String> dict, HashMap<String, List<String>> map) {
        if (map.containsKey(s))
            return (ArrayList<String>) map.get(s);
         
        ArrayList<String> lists = new ArrayList<>();
        if (s.equals("")) {
            lists.add("");
            return lists;
        }
        int len = s.length();
        for (int i = 1; i <= len; i++) {
            String sub = s.substring(0, i);
            if (dict.contains(sub)) {
                ArrayList<String> t = dfs(s.substring(i, len), dict, map);
                if (t.size() == 0) {
                    continue;
                }
                for (int j = 0; j < t.size(); j++) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(sub).append(" ").append(t.get(j));
                    lists.add(sb.toString().trim());
                }
            }
        }
        map.put(s, lists);
        return lists;
    }
    
    public static void main(String[] args)
    {
        String s ="catsanddog";
        String[] dict = {"cat", "cats", "and", "sand", "dog"};
        Set<String> set = new HashSet<>(Arrays.asList(dict));
        WordBreakII wordBreak = new WordBreakII();
        System.out.println(wordBreak.wordBreak1(s, set));
        System.out.println(wordBreak.wordBreak(s, set));
    }

}

           

参考:

[LeetCode] Word Break II 拆分词句之二