zoukankan      html  css  js  c++  java
  • 【Word Break II】cpp

    题目:

    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"].

    代码:

    class Solution {
    public:
            vector<string> wordBreak(string s, unordered_set<string>& wordDict)
            {
                vector<string> ret;
                vector<string> tmp;
                vector<bool> possible(s.size(), true);
                Solution::dfs( possible, wordDict, ret, tmp, s, 0, s.size()-1);
                return ret;
            }
            static void dfs( 
                vector<bool>& possible, // possible[i] : if s[i~end] can be possible word broken 
                unordered_set<string>& wordDict, 
                vector<string>& ret, 
                vector<string>& tmp, 
                string& s, int begin, int end )
            {
                if ( begin>end )
                {
                    string str = "";
                    for ( int i=0; i<tmp.size(); ++i ) { str = str + tmp[i] + " "; }
                    ret.push_back(str.substr(0,str.size()-1));
                }
                for ( int i=begin; i<=end; ++i )
                {
                    if ( wordDict.find(s.substr(begin,i-begin+1))!=wordDict.end() && possible[i] )
                    {
                        tmp.push_back(s.substr(begin,i-begin+1));
                        int oriSolution = ret.size();
                        Solution::dfs( possible, wordDict, ret, tmp, s, i+1, end);
                        if ( oriSolution==ret.size()) possible[i]=false;
                        tmp.pop_back();
                    }
                }
            }
    };

    tips:

    其实在word break i这道题的时候就想用dfs做,但是会超时。

    word break ii这道题是求所有可行解,就尤其想用dfs来做。

    一开始写了一版裸dfs的代码,发现会超时:原因是没有剪枝。

    这里学习了一下大神的剪枝技巧(http://fisherlei.blogspot.sg/2013/11/leetcode-wordbreak-ii-solution.html

    这里的possible[i] 代表的是 s[i+1:s.size()-1] 可否被给定的wordDict来word break。翻译过来就是,从i往后(不包括i)是否行可以被wordDict表示。

    这个思路很精妙:

    1. 从给定当前点往后看,看能否满足条件。这样dfs下次再走到这个点的时候,就知道是否可以往下走了。

    2. 为什么不把possible[i]当成s[0~i]是否满足条件呢?因为能来到位置i的方式有很多种,一种方式行不通不代表其他方式行不通

    3. 由i往后,一直到end,已经把所有可能走到最后的方式都包括了,如果所有可能走到最后的方式中都行不通,那就是肯定行不通了

    4. 如何记录是否行得通了呢?我就是卡在这里了,没想到太好的办法。这时学习了大神的办法,比较下解集的个数:如果个数没变,那肯定是行不通了。

    ===============================================

    第二次过这道题,复习遍原来的方法。

    class Solution {
    public:
        vector<string> wordBreak(string s, unordered_set<string>& wordDict)
        {
            vector<string> ret;
            vector<string> tmp;
            vector<bool> possible(s.size(),true);
            Solution::dfs(ret, tmp, 0, s.size()-1, s, wordDict, possible);
            return ret;
        }
        static void dfs(
            vector<string>& ret,
            vector<string>& tmp, 
            int begin,
            int end,
            string& s,
            unordered_set<string>& wordDict,
            vector<bool>& possible
            )
        {
            if ( begin>end )
            {
                string str = "";
                for ( int i=0; i<tmp.size(); ++i ) str += tmp[i] + " ";
                ret.push_back(str.substr(0,str.size()-1));
                return;
            }
            for ( int i=begin; i<=end; ++i )
            {
                if ( wordDict.find(s.substr(begin, i-begin+1))!=wordDict.end() && possible[i] )
                {
                    tmp.push_back(s.substr(begin, i-begin+1));
                    int pre = ret.size();
                    Solution::dfs(ret, tmp, i+1, end, s, wordDict, possible);
                    if ( ret.size()==pre ) possible[i] = false;
                    tmp.pop_back();
                }
            }
        }
    };
  • 相关阅读:
    vue实例讲解之vuex的使用
    实例讲解webpack的基本使用第一篇
    如何写一个jquery插件
    《改变你一生的108个心理学法则》读书笔记
    用css绘制各种图形
    关于js浮点数计算精度不准确问题的解决办法
    非常有用的css使用总结
    网页meta标签总结
    Object.defineProperty()方法的用法详解
    js中set和get的用法
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4553674.html
Copyright © 2011-2022 走看看