小白日更第十四天->力扣第139题(单词拆分)

话不多说,先看题目描述:

其实在刚才我做这道题目的时候,因为我知道这是动态规划的题目,因为我这段时间重心都放在动态规划上面,所以既然已经知道了DP,那他肯定是递归演化而来的,在我的上一篇文章中也说了,动态规划的演变过程,具体如下

1、递归(问题是许多子问题重复计算了,导致耗费时间)

2、备忘录递归(其实效率已经和动态规划已经是一样的了,只不过这种方法是自↑向↓,动态规划是自↓向↑

3、动态规划(其实就是在第二步的基础上从最开始计算,比如我们斐波那契数列,f(10)=f(9)+f(8),备忘录方法会先计算f(9)和f(8),而动态规划是从f(2)开始计算,先初始化f(0)和f(1),不知道举的这个例子大家能不能明白)

那我们分析这道题目,其实我第一想到的是KMP算法,就是比如一个字符串s=“ABCDEFG”,wordDict[“ABC”,“EFG”],那我先用一个for循环从A开始遍历,如果遍历到s中的C,那这个时候我们就把ABC从字符串s中删除掉,然后判断s剩下的是否还能被拆分成wordDict中的字段。那这也太麻烦了,并且这道题不是KMP算法的题目呀,因为KMP算法是判断一个字符串中是否包含另一个字符串,比如ABCDEFG中是否包含BCDF,但是题目中给的wordDict是一个数组里面有n个字符串。所以我们就要转换思路。

其实我们很容易想到,如果给定s中的第五个位置也就是说从s[0]到s[4]是否在wordDict中存在,如果存在的话,那我们再判断n+1的位置是否再wordDict中不就可以了吗,比如现在判断s[10],我们从s[9]判断,如果是s[9]存在于wordDict中,那就很简单了,我们再判断一下wordDict中是否包含s[10]不就可以了吗?如果s[10]不存在于wordDict中我们就继续向前遍历,也就是判断s[8]是否是可拆分的,如果s[8]可拆分,那我们就判断是s[9]-s[10]是否在wordDict中不就可以了吗?这一步很简单我们直接用截取字符串的方式就可以了,既然思路我们已经分析完了,那代码实现起来就不是很难了。

public HashMap<String, Boolean> hash = new HashMap<>();
    public boolean wordBreak(String s, List<String> wordDict) {
        boolean[] dp = new boolean[s.length()+1];
        //我们先把wordDict中的值放到map里面,并且赋初始值为true,这样我们在判断比如上面提到的s[9]-s[10]是否在wordDict中,如果在就返回true,不存在就返回true。
        for(String word : wordDict){
            hash.put(word, true);
        }

        //初始化因为字符串中是从数组下表0开始的
        dp[0] = true;

        //从字符串的第一个字符开始依次遍历
        for(int i = 1; i <= s.length(); i++){
            for(int j = i-1; j >= 0; j--){
                dp[i] = dp[j] && check(s.substring(j, i));//这里我们进行判断
                if(dp[i])   break;//如果我们在某次循环中已经做出判断dp[i]是可以拆分的,那我们就没必要继续向前遍历了,也许继续向前遍历也能进行单词拆分,但是没必要,题目要求返回的是boolean,你只需要判断能不能进行拆分就可以了呀。
            }
        }
        return dp[s.length()];
    }

    public boolean check(String s){
        return hash.getOrDefault(s, false);//这个方法就相当于有在map中存在s这个key就返回它的值,如果不存在就返回false
    }

解释我都在代码中注释了,应该把小伙伴们看不懂的地方都进行了说明,如果还有哪块不懂或者我写错的地方,欢迎大家在评论区留言讨论~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值