zoukankan      html  css  js  c++  java
  • 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.

    Retun all such possible sentences.

    For example, given
    s = "catsanddog",
    dict = ["cat", "cats", "and", "sand", "dog"].

    A solution is ["cats and dog", "cat sand dog"].

    Have you been asked this question in an interview? 

    A  clever way:

    public class Solution {
    	public List<String> wordBreak(String s, Set<String> dict) {
    		List<String> result = new ArrayList<String>();
    		List<List<Integer> > split = new ArrayList<List<Integer> >();
    		boolean[] cuts = new boolean[s.length() + 1];
    		if(s.length() > 0 && dict.size() > 0) {
    			split.add(0, new ArrayList<Integer>());
    			cuts[0] = true;
    			for(int i = 1; i < s.length() + 1; ++i) {
    				cuts[i] = false;
    				List<Integer> currentSplit = new ArrayList<Integer>();
    				for(int j = 0; j < i; ++j) {
    					if(!cuts[j]) continue;
    					else {
    						if(dict.contains(s.substring(j, i))){
    							if(!cuts[i])
    								cuts[i] = true;
    							currentSplit.add(j);
    						}
    					}
    				}
    				split.add(currentSplit);
    			}
    			//build splits
    			if(!split.get(s.length()).isEmpty())
    				buildSplit(s, split,s.length(), result);
    		}
    		return result;
    	}
    		
    	//dfs method
    	private void buildSplit(String s, List<List<Integer> > split, int i, List<String> result){ 
    		List<Integer> insertBlank = split.get(i);
    		for(int j : insertBlank){
    			StringBuffer aCopy = new StringBuffer(s);
    			if(j != 0){
    				aCopy.insert(j,  " ");
    				buildSplit(aCopy.toString(), split, j, result);
    			}
    			else
    				result.add(s);
    		}
    	}
    }
    

     

    In this post, I used a very stupid method to solve this problem:

    1. Using the dynamic programming method to find all possible position to cut the string(The same as Word Break)

    This step will return a boolean matrix, if(i,j) entry is true then the substring s.substring(i,j) can be splitted.

    2. Using the boolean matrix obtained in step1, we do DFS to obtain all strings.

    public class Solution {
        public ArrayList<String> wordBreak(String s, Set<String> dict) {
            ArrayList<String> result = new ArrayList<String>();
    		if(s == null || dict.size() == 0)
    			return result;
    		//find the position to split the string
    		int len = s.length();
    		boolean[][] splits = new boolean[len][len + 1];
    		for(int i = len - 1; i >= 0; --i){
    			splits[i][i] = false;
    			for(int j = i + 1; j < len + 1; ++j){
    				if(dict.contains(s.substring(i, j)))
    					splits[i][j] = true;
    				else{
    					for(int k = i; k < j; ++k){
    						splits[i][j] = splits[i][k] && splits[k][j];
    						if(splits[i][j])
    							break;
    					}
    				}
    			}
    		}
    		//find the possible splitting of the string
    		//I use dfs method to solve this.
    		if(splits[0][len]){
    			ArrayList<ArrayList<Integer>> resultInPosition = new ArrayList<ArrayList<Integer>>();
    			HashMap<Integer, ArrayList<ArrayList<Integer>> > finished = new HashMap<Integer,ArrayList<ArrayList<Integer>> >();
    		       	for(int i = len - 1; i >= 0; --i){
    				ArrayList<ArrayList<Integer>> startAti = new ArrayList<ArrayList<Integer>>();
    				if(splits[i][len]){
    					if(dict.contains(s.substring(i, len))){
    						ArrayList<Integer> aList = new ArrayList<Integer>();
    						aList.add(len);
    						startAti.add(aList);
    					}
    					for(int j = i + 1; j < len; ++j){
    						if(dict.contains(s.substring(i,j)) && splits[j][len]){
    							ArrayList<ArrayList<Integer> > fin = finished.get(j);
    							for(ArrayList<Integer> ls : fin){
    								ArrayList<Integer> temp = new ArrayList<Integer>();
    								temp.add(j);
    								temp.addAll(ls);
    								startAti.add(temp);
    							}			
    						}		
    					}
    				}
    				finished.put(i, startAti);
    			}
    			resultInPosition = finished.get(0);
    			for(ArrayList<Integer> ls : resultInPosition){
    				int lssize = ls.size();
    			       	int first = ls.get(0);	
    				String resultString = s.substring(0, first);
    				for(int i = 1; i < lssize; ++i){
    					resultString += (" "+ s.substring(first, ls.get(i)));
    					first = ls.get(i);
    				}
    				result.add(resultString);			
    			}
    					
    		}
    		return result;
        }
    }
    

    I tested this code on leetcode online judge, it was accepted and it used 450ms for 24 test cases. I think it is ok although it may not be the best.  

  • 相关阅读:
    GDB 进行调试 使用心得
    libnet发包例子(tcp udp arp广播)
    epoll源码实现分析[整理]
    Linux中的时间和时间管理
    PHP生成压缩文件开发实例
    sql语句删除数据表重复字段的方法
    亿级Web系统搭建——单机到分布式集群
    微信开发之附近商家地理位置计算和腾讯地图坐标转百度地图坐标的方法
    PHP生成订单号(产品号+年的后2位+月+日+订单号)
    (用微信扫的静态链接二维码)微信native支付模式官方提供的demo文件中的几个bug修正
  • 原文地址:https://www.cnblogs.com/averillzheng/p/3572752.html
Copyright © 2011-2022 走看看