• lintcode107- Word Break- medium


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

    Example

    Given s = "lintcode", dict = ["lint", "code"].

    Return true because "lintcode" can be break as "lint code".

    算法:用DP。f[x]定义为substring(0,x)能不能break。f[x] = {f[i] && dict.contains(substring(i, x))} | 对所有x之前,末尾单词substring(i,x)长度是小于最长单词长度的。

    第二个空间优化(避免MLE):

    1.避免写递归DFS(和Palindrome partitioning很像,都是如果求全部答案的话用DFS,但如果只求一个最优答案所需要的步数用DP。)

    2.避免写出遍历所有长度substring的写法,因为substring用的空间复杂度时间复杂度是和string长度成正比的,这里要做一个只需要遍历dict里面最长单词长度的substring的优化(因为长度更长的单词肯定不会存在dict里了,没必要看)。

    细节:小心cornercase s == ""。这种不但要考虑dict为空,比较字符串也要考虑为空。

    1.DP。

    public class Solution {
        /*
         * @param s: A string
         * @param dict: A dictionary of words dict
         * @return: A boolean
         */
        public boolean wordBreak(String s, Set<String> dict) {
            // write your code here
            
            if (dict == null) {
                return false;
            }
            if (s.equals("")) {
                return true;
            }
            
            int maxLength = Integer.MIN_VALUE;
            for (String word : dict) {
                maxLength = Math.max(maxLength, word.length());
            }
            // canBreak[i] 代表s.substring(0,i+1)能不能被break, 0< i < s.length() 
            boolean[] canBreak = new boolean[s.length() + 1];
            canBreak[0] = true;
            // 问题就在于不能直接遍历所有长度的substring!那就会超空间复杂度,要做一个调查substring长度小于maxLength的优化!!!!
            
            // for (int i = 0; i < s.length(); i++) {
            //     if (dict.contains(s.substring(0, i + 1))) {
            //         canBreak[i] = true;
            //     }
            // }
            
            for (int i = 1; i <= s.length(); i++) {
                for (int j = i - maxLength; j < i; j++) {
                    if (j < 0) {
                        continue;
                    }
                    if (canBreak[j] && dict.contains(s.substring(j, i))) {
                        canBreak[i] = true;
                        break;
                    }
                }
            }
            return canBreak[s.length()];
        }
        
        
    }

    2.递归写法(爆了MLE)

    public class Solution {
        /*
         * @param s: A string
         * @param dict: A dictionary of words dict
         * @return: A boolean
         */
        public boolean wordBreak(String s, Set<String> dict) {
            // write your code here
            
            if (dict == null) {
                return false;
            }
            
            if (dict.contains(s) || s.equals("")) {
                return true;
            }
            
            for (int i = 1; i < s.length(); i++) {
                if (dict.contains(s.substring(0, i)) && wordBreak(s.substring(i, s.length()), dict)) {
                    return true;
                }
            }
            
            return false;
        }
        
        
    }
  • 相关阅读:
    centos的DNS服务工作流程及搭建
    将博客搬至CSDN
    全自动网络安装centos(一)安装前准备工作
    网站私有CA证书制作
    LINUX之启动流程
    脚本判断选择语句常用命令
    linux 常用端口
    linux之网卡绑定
    centos7 无法启动网络(service network restart)错误解决办法(转)
    Linux的磁盘配额详解(Quota)
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7791462.html
Copyright © 2020-2023  润新知