• leetcode-word break-ZZ


    题目, 反正就是一个string,要不自己在字典里,要不切几刀,切出来的每个词都在字典里

    ———————————————————————————————————————————————————————-

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

    For example, given
    s = "leetcode",
    dict = ["leet", "code"].

    Return true because "leetcode" can be segmented as "leet code".

    ———————————————————————————————————————————————————————-

    最笨的解法,DFS

    public class Solution {
        public boolean wordBreak(String s, Set<String> dict) {
            // IMPORTANT: Please reset any member data you declared, as
            // the same Solution instance will be reused for each test case.
            if (dict.contains(s)) return true;
            if (s==null || s.length()==0) return false;
            return helper(s, 0, dict);
        }
    
        public boolean helper(String s, int i, Set<String> dict) {
            int n = s.length();
            if (i>=n) return false;
            int j = i;
            while (j<n) {
                while(j<n && !dict.contains(s.substring(i,j+1))) {
                    j++;
                }
                if (j==n) return false;
                boolean goodAfter = helper(s, j+1, dict);
                if (goodAfter) return true;
                j++;
            }
            return false;
        }
    }

    我不确定对: 没有额外空间,空间O(1)。每次recursion,都要loop O(n), 时间O(n^n)

    毫无意外是会超时的,要加速基本要上DP了。关键是DP记录什么东西不好想,反正我是想了很久都没想到。最后看了大牛的答案才明白。还是bottom up approach。比如String长度为0,问题成立吗? 然后String长度为1,成立吗? 一直到n。所以dp就是记录从头开始的substring的长度和问题能否成立的关系。关键是dp[i]怎样可以利用dp[k], k=0,.., i-1的结果?就要在找0到i-1中找到一个k,使得dp[k] && dict.contains(s.substring(k, i))为真。意义是从0到k-1之间的substring,已经有办法用字典的词组成了,而且如果k到i-1之间的substring也在字典里,那么从0开始,长度为i的string就可以由字典里的词组成。

    注意的是dp[0] == true是因为如果整个词都在字典里,那么就可以由字典的词组成。

    优化解法:一维DP

    public class Solution {
        public boolean wordBreak(String s, Set<String> dict) {
            int n = s.length();
            boolean[] dp = new boolean[n+1];
            dp[0] = true;
            for (int i=1; i<=n; i++) {
                for (int j=0; j<i; j++) {
                    if (dp[j] && dict.contains(s.substring(j,i))) {
                        dp[i] = true;
                        break;
                    }
                }
            }
            return dp[n];
        }
    }
    

    空间 O(n), 时间O(n^2)

    这种方法好像在leetcode很常见,以后要总结一下。

    http://stupidcodergoodluck.wordpress.com/2013/11/15/leetcode-word-break/

  • 相关阅读:
    笔试题 输出金字塔 面试经典
    C++ 函数, 虚函数, 纯虚函数
    EJB 根据beanName引用EJB
    【J2EE性能分析篇】JVM参数对J2EE性能优化的影响【转】
    C++ 引用和指针作为函数参数的例子。请不要拍砖
    lucene 总结
    二维数组按列序号排序 面试经典
    http://www.linuxidc.com/Linux/201004/25494.htm
    银行取款费用
    PHP 生成 csv 文件时乱码解决
  • 原文地址:https://www.cnblogs.com/forcheryl/p/3997290.html
Copyright © 2020-2023  润新知