zoukankan      html  css  js  c++  java
  • 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;
        }
        
        
    }
  • 相关阅读:
    DDD(Domain Driven Design) 架构设计
    兴哥:美团下一个十年,要让新一批管理者成长起来
    Java设计模式-Builder构造者模式
    社会需要转型变革,自己更需要转型变革-屡败屡战
    Guava 源码分析之Cache的实现原理
    缓存算法(FIFO 、LRU、LFU三种算法的区别)
    Guava---缓存之LRU算法
    Boost.Asio 网络编程([译]Boost.Asio基本原理)
    浅谈 Boost.Asio 的多线程模型
    boost.asio系列——io_service
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7791462.html
Copyright © 2011-2022 走看看