ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LeetCode 139. 单词拆分

2020-06-25 09:52:43  阅读:302  来源: 互联网

标签:单词 wordDict boolean 拆分 字符串 139 LeetCode dp


题目链接

139. 单词拆分

题目分析

这个题要求我们去检查s是否能拆分成字典集合中的单词,其中字典集中可以把重复出现的单词看做一个。
我们仔细看第三个测试用例,可以发现他说的拆分就是你一个字母不能同时属于两个新单词。
这个题第一次做不会,后来看了题析才知道是DP问题,今天这个题作为每日一题, 自然而然可以秒杀了。
我们定义一个boolean数组,如果字符串的子串substring(j,i)可以拆分成字典集合里面的单词,我们就将dp[i]置为true.
当然这个也是有个前提的,这个拆分的前一个字符必须也能被拆分成另外一个单词,否则我们当前的拆分可能是重复利用了同一个字符。

代码实现

class Solution {
    /**
     * LC 139.单词拆分
     * 传统DP问题
     * 2020年6月25日
     * @param s
     * @param wordDict
     * @return
     */
    public boolean wordBreak(String s, List<String> wordDict) {
        //注意,这里必须要长一位,因为0号位会被作为标志位来使用。
        boolean[] dp = new boolean[s.length()+1];
        //dp[0]其实就是空字符串,空字符串必定在另外一个非空字符串的集合中。
        dp[0] = true;
        //外层的i用于控制当前字符串的右边界,所以会是小于等于s.length()
        for(int i = 1; i <= s.length(); i++){
            //内层的j用于控制左边界,慢慢去收缩这个边界。
            for(int j = 0; j < i; j++){
                //注意!这里判断条件有两个,第一个是当前剪切下来的字符串在字典中是否存在
                //第二个是要检查我们dp[j]就是我们的前一位字符是否被正确匹配,如果这个不成立
                //说明我们可能重复利用了某个字符,这样会导致单词划分有了重复。
                if(dp[j] && wordDict.contains(s.substring(j,i))){
                    dp[i] = true;
                    break;
                }
            }
        }
        //返回最后那个位置的值
        return dp[s.length()];
    }
}

后记

做完后又详细看了下评论区,真的挺NB的,我的实现代码是没有经过任何剪枝的,导致只击败了20%左右的人。但是这个题其实可以剪枝剪的很厉害,例如:

  • 我们可以在字典集中找最长的字符串,记录其长度为maxW,然后在内层循环中从右边界向左拓展,直到右边界小于0或者小于i-maxW
  • 我们可以记录字典中最短的字符串长度为minW,我们外层循环最开始可以直接从minW处开始做起

通过以上的剪枝操作,我们可以将代码优化到击败99%的人。

后记代码实现

class Solution {
    /**
     * LC 139.单词拆分
     * 传统DP问题
     * 2020年6月25日
     * @param s
     * @param wordDict
     * @return
     */
    public boolean wordBreak(String s, List<String> wordDict) {
        int len = s.length(), maxw = 0, minw = Integer.MAX_VALUE;
        boolean[] dp = new boolean[len + 1]; 
        dp[0] = true;
        Set<String> set = new HashSet();
        for(String str : wordDict){
            set.add(str);
            maxw = Math.max(maxw, str.length());
            minw = Math.min(minw, str.length());
        }
        for(int i = minw; i < len + 1; i++){
            for(int j = i; j >= 0 && j >= i - maxw; j--){
                if(dp[j] && set.contains(s.substring(j, i))){
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[len];
    }
}

标签:单词,wordDict,boolean,拆分,字符串,139,LeetCode,dp
来源: https://www.cnblogs.com/ZJPaang/p/13191162.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有