2020-11-01

11.1每日一题

140. 单词拆分 II

这道题是139题的拓展,所以先来解决139,139是判断字符串是否可以拆分成字典中的单词,可以想到使用动态规划的方法来解决这道题,设dp[i]是长度为i的字符串能否拆分成单词,那么将字符串i拆解成(0,j)和(j,i)如果这两个字符串都是在字典中出现的单词,那么组合后的i也是字典中的单词,因此转移方程为:dp[i] = dp[j] && wordDict.contains(s.substring(j, i)),当i = 0,即字符串长度为0,规定为合法,理清楚之后就可以写代码了。

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        //首先创建一个hash表方便快速判断字符串是否在字典内
        int len = s.length();
        Set<String> wordDictSet = new HashSet<>(wordDict);
        boolean[] dp = new boolean[len + 1];
        //初始化边界值
        dp[0] = true;
        for(int i = 1; i <= len; i++){
        	//如果单词长度比较短,从后遍历比较快
        	for(int j = i - 1; j >= 0; j--){
        		if(dp[j] && wordDictSet.contains(s.substring(j, i))){
        			dp[i] = true;
        			//找到一个证明正确就可以返回了
        			break;
        		}
        	}
        }
        return dp[len];
    }
}

做完了139前置题之后,可以来解决今天的每日一题了,看到题目中提到的所有解,可以想到回朔来解题,再结合139的动态规划就基本可以做出来了。

class Solution {
    public List<String> wordBreak(String s, List<String> wordDict) {
        //首先创建一个hash表方便快速判断字符串是否在字典内
        int len = s.length();
        Set<String> wordDictSet = new HashSet<>(wordDict);
        boolean[] dp = new boolean[len + 1];
        //初始化边界值
        dp[0] = true;
        for(int i = 1; i <= len; i++){
        	//如果单词长度比较短,从后遍历比较快
        	for(int j = i - 1; j >= 0; j--){
        		if(dp[j] && wordDictSet.contains(s.substring(j, i))){
        			dp[i] = true;
        			//找到一个证明正确就可以返回了
        			break;
        		}
        	}
        }
        //回朔找出所有解
        List<String> res = new ArrayList<>();
        if(dp[len]){
        	Deque<String> path = new ArrayDeque<>();
        	dfs(s, len, wordDictSet, dp, path, res);
        	return res;
        }
        return res;
    }
    void dfs(String s, int len, Set<String> wordDictSet, boolean[] dp, Deque<String> path, List<String> res){
    	//终止条件
    	if(len == 0){
    		res.add(String.join(" ", path));
    		return;
    	}
    	for(int i = len - 1; i >= 0; i--){
    		String suffix = s.substring(i, len);
    		if(wordDictSet.contains(suffix) && dp[i]){
    			path.addFirst(suffix);
    			dfs(s, i, wordDictSet, dp, path, res);
    			path.removeFirst();
    		}
    	}
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值