题解 | #单词拆分(一)#

单词拆分(一)

http://www.nowcoder.com/practice/c0d32c1ce5744472a01b2351a2c2767f

题目描述:

给定一个字符串和一个字符串数组,判断是否存在将字符串任意划分后得到的子字符串都是字符串数组的子集

方法一:动态规划

  • 首先,确定dp数组下标以及含义,dp[i]表示s[0,i]是否是字符串数组的子集。

  • 确定递推公式,枚举结束位置end,在0到end之间枚举开始位置start,当s[0,start]是set的子集,如果s[start,end]也是set的子集,推出dp[end]=truedp[end]=true

  • 从递推公式可以看出dp[j]是依赖于前面先推出的值,我们需要先初始化dp[0]为true,即空集为集合的子集。

alt

  • 确定遍历顺序,从上图可以看出遍历顺序是从左到右
function wordDiv( s ,  dic ) {
    // write code here
    var dp=[s.length+1];
    var set=new Set(dic);
    dp[0]=true;
    for(let i=1;i<s.length+1;i++ ){
        for(let j=0;j<i;j++){
            if(dp[j]&&set.has(s.substring(j,i))){
                dp[i]=true;
                break;
            }
        }
    }
    return dp[s.length];
}
module.exports = {
    wordDiv : wordDiv
};

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param dic string字符串一维数组 
     * @return bool布尔型
     */
    public boolean wordDiv (String s, String[] dic) {
        // write code here
        HashSet<String> set = new HashSet<>();
        for(String word: dic){
            set.add(word);//先移除重复字符串
        }
        boolean[] dp = new boolean[s.length() + 1];//dp[i]表示s字符串中前i个字符是不是set的子集
        dp[0] = true;//空串可以被词表中的词表示
        for(int end = 1; end <= s.length(); end++){
            for(int start = 0; start < end; start++){
                if(dp[start] && set.contains(s.substring(start, end))){
                    //s[0:start]是set的子集,s[start:end]也是set的子集,所以s[0:end]是set的子集,dp[end]=true
                    dp[end] = true;
                    break;
                }
            }
        }
        return dp[s.length()];
    }
}

复杂度:

  • 时间复杂度:O(n2)O(n^{2}),双重循环。
  • 空间复杂度:O(n)O(n),dp数组和集合set均占用空间
全部评论
方法2是错的,比如说"abcd",{"a","abc","d"}得出的结果是 false
点赞 回复 分享
发布于 2022-07-01 14:52
方法二有bug
点赞 回复 分享
发布于 2022-04-16 15:33
根本就通不过啊 "nowscoder",["now","coder","nows"]
点赞 回复 分享
发布于 2022-04-16 15:33

相关推荐

02-07 12:06
已编辑
华侨大学 测试开发
最近看到很多&nbsp;92&nbsp;的,甚至是硕士,开始往测开赛道卷,说实话有点看不懂。先把话说清楚,大厂里的测开,绝大多数时间干的还是测试的活,只是写点自动化脚本、维护测试平台、接接流水线,真正像开发一样做系统、做架构、做核心平台的测开少得可怜,基本都集中在核心提效组,而且人很少,外面进去的大概率轮不到你,我想真正干过人都清楚。很多人被洗脑了,以为测开也是开,和后端差不多,只是更简单、更轻松、还高薪。现实情况是,测开和开发的职业路径完全不一样。开发的核心是业务和系统能力,测开的核心是稳定性和覆盖率,前者是往上走,后者天花板非常明显。你可以见到很多开发转测开,但你很少见到干了几年测开还能顺利转回开发的。更现实一点说,92&nbsp;的高学历如果拿来做测开,大部分时间就是在做重复性很强的杂活,这种工作对个人能力的放大效应非常弱。三年下来,你和一个双非的,甚至本科的测开差距不会太大,但你和同龄的后端、平台开发差距会非常明显。这不是努不努力的问题,是赛道问题。所谓测开简单高薪,本质上是把极少数核心测开的上限,当成了整个岗位的常态来宣传。那些工资高、技术强的测开,本身就是开发水平,只是挂了个测开的名。普通人进去,99%&nbsp;做的都是项目兜底型工作,而不是你想象中的平台开发。测开不是不能做,但它绝对不是开发的平替,也不是性价比最优解。如果你是真的不想做开发,追求稳定,那测开没问题。但如果你只是觉得测开比后端容易,还能进大厂,那我劝你冷静一点,这只是在用短期安全感换长期天花板。有92的学历,如果你连测开这些重复性工作都能心甘情愿接受,那你把时间精力用在真正的开发、系统、业务深度上,回报大概率比卷测开要高得多。想清楚再下场,别被岗位名和话术带偏了,就算去个前端客户端也是随便占坑的,测开是一个坑位很少赛道,反而大面积学历下放,不用想也能知道会是什么结果,我想各位在JAVA那里已经看到了
小浪_Coding:工作只是谋生的手段 而不是相互比较和歧视
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务