【leetcode】139.单词拆分

文章介绍了两种方法解决给定字符串s是否可以通过字典中的单词拼接而成的问题,一种是回溯法,通过检查已选单词是否构成目标串的前缀;另一种是动态规划,通过构建dp数组存储每个位置是否能由字典单词组成。
摘要由CSDN通过智能技术生成

题目:

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

方法一:回溯法

回溯法其实很简单 就是每次选择一个单词去排列组合 (因为这里是可以重复选的 所以你回溯的起始位置不用往后加 也就是说每次选择你都要从头开始去选)这个方法的改进就是在做选择的时候或者是判断是否结束回溯的时候 去**匹配已选的字符串是否是目标串的前缀 **因为目前的结果如果都不是前缀 往后再继续选也不会是正确答案
这个方法是无法过力扣的测试用例的 因为时间复杂度太高了

class Solution {
    String singleResult;
    boolean result;
    public void chooseString(int begin,String s,List<String> wordDict){
        System.out.println("-------------------------------");
        if(result||singleResult.length()>s.length()){
            return;
        }
        if(singleResult.length()==s.length()&&singleResult.equals(s)){
            result=true;
            return;
        }
        System.out.println("singleResult:"+singleResult);
        if(singleResult.length()>0&&singleResult.length()<=s.length()){
            String head=s.substring(0,singleResult.length());
            System.out.println("head:"+head);
            if(!singleResult.equals(head)){
                return;
            }
        }
        
        
        for(int i=begin;i<wordDict.size();i++){
            String temp=singleResult;
            singleResult=singleResult+wordDict.get(i);
            chooseString(begin,s,wordDict);
            singleResult=temp;
        }
    }

    public boolean wordBreak(String s, List<String> wordDict) {
        singleResult="";
        result=false;
        chooseString(0,s,wordDict);
        return result;
    }
}

方法二:动态规划

题目是单词拆分 我们转换思路 其实就是去选wordDict里面的单词组成目标字符串
解题思路如图下所示:
1aa7684a33c89480195b373fb022e87.jpg

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        boolean[] dp=new boolean[s.length()+1];
        Arrays.fill(dp,false);
        // 如果dp[0]是false那么后面推理的都是false
        dp[0]=true;
        for(int i=1;i<=s.length();i++){
            System.out.println("--------");
            for(int j=0;j<i;j++){
                if(dp[i]==true){
                    break;
                }
                String sub=s.substring(j,i);
                System.out.println("sub:"+sub);
                if(wordDict.contains(sub)){
                    dp[i]=dp[j];
                }else{
                    dp[i]=false;
                }
            }
        }
        return dp[s.length()];
    }
}
  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值