*[leetcode]Word Break II

在DP的时候记录前驱节点的值到数组,然后DFS该数组构造结果。做完这道题,有种“宋元明清后,王朝至此完”的赶脚。

import java.util.*;
public class Solution {
    public ArrayList<String> wordBreak(String s, Set<String> dict) {
        int len = s.length();
        boolean f[] = new boolean[len + 1];
        ArrayList<ArrayList<Integer>> prev = new ArrayList<ArrayList<Integer>>();
        for (int i = 0; i <= len; i++) {
            prev.add(new ArrayList<Integer>());
        }
        f[0] = true;
        for (int i = 1; i <= len; i++) {
            for (int j = i - 1; j >= 0; j--) {
                if (f[j] && dict.contains(s.substring(j, i))) {
                    prev.get(i).add(j);
                    f[i] = true;
                }
            }
        }
        ArrayList<String> result = new ArrayList<String>();
        buildResult(s, prev, len, result, "");
        return result;
    }
    
    private void buildResult(String s, ArrayList<ArrayList<Integer>> prev, int end, ArrayList<String> result, String current) {
        ArrayList<Integer> prevs = prev.get(end);
        for (int i = 0; i < prevs.size(); i++) {
            int n = prevs.get(i);
            String sub = s.substring(n, end);
            String r = sub;
            if (!current.equals("")) {
                r = r + " " + current;
            }
            if (n == 0) {
                result.add(r);
            }
            else {
                buildResult(s, prev, n, result, r);
            }
        }
    }
}

第二刷,DFS果然超时,但是DFS之前先用DP记录什么子串是不能成功的,可以减少试错,但仍然是上面的方法好:

class Solution {
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        vector<string> res;
        if (!wordBreakPossible(s, dict)) return res;
        
        wordBreakRe(s, dict, 0, res, "");
        return res;
    }

    void wordBreakRe(string &s, unordered_set<string> &dict, int idx,
        vector<string> &result, string tmp)
    {
        if (idx == s.size())
        {
            result.push_back(tmp);
            return;
        }
        if (idx != 0) tmp.push_back(' ');
        for (int i = idx; i < s.size(); i++)
        {
            string sub = s.substr(idx, i - idx + 1);
            if (dict.find(sub) != dict.end())
            {
                wordBreakRe(s, dict, i + 1, result, tmp+sub);
            }
        }
    }
    
    bool wordBreakPossible(const string &s, const unordered_set<string> &dict) {
        int N = s.size();
        vector<bool> possible;
        possible.resize(N + 1);
        
        possible[0] = true; // s with len == 0
        for (int i = 1; i <= N; i++)
        {
            for (int j = 0; j < i; j++)
            {
                string sub = s.substr(j, i - j);
                if (possible[j] && dict.find(sub) != dict.end())
                {
                    possible[i] = true;
                }
            }
        }
        return possible[N];
    }
};

  

posted @ 2013-10-16 23:00  阿牧遥  阅读(1185)  评论(0编辑  收藏  举报