zoukankan      html  css  js  c++  java
  • leetcode 139: 单词拆分

    package com.example.lettcode.dailyexercises;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Class WordBreak
     * @Description 139. 单词拆分
     * 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,
     * 判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
     * <p>
     * 说明:
     * 拆分时可以重复使用字典中的单词。
     * 你可以假设字典中没有重复的单词。
     * <p>
     * 示例 1:
     * 输入: s = "leetcode", wordDict = ["leet", "code"]
     * 输出: true
     * 解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。
     * <p>
     * 示例 2:
     * 输入: s = "applepenapple", wordDict = ["apple", "pen"]
     * 输出: true
     * 解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
     * 注意你可以重复使用字典中的单词。
     * <p>
     * 示例 3:
     * 输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
     * 输出: false
     * @Author 
     * @Date 2020/6/25
     **/
    public class WordBreak {
    }
    
    /**
     * 解法1:利用递归和回溯,超时
     */
    public static boolean wordBreak(String s, List<String> wordDict) {
    	return subWordBreak(s, wordDict, 0);
    }
    
    private static boolean subWordBreak(String s, List<String> wordDict, int start) {
    	// 结束条件,当字符串s遍历结束,说明字符串s全部匹配,
    	if (start == s.length()) return true;
    
    	for (int end = start + 1; end <= s.length(); end++) {
    		// 如果s[start,end) 匹配wordDict中的某个单词,并且s[end,..] 也可以拆分;
    		if (wordDict.contains(s.substring(start, end)) && subWordBreak(s, wordDict, end)) {
    			return true;
    		}
    	}
    	// 没有找到匹配的单词
    	return false;
    }
    
    /**
     * 解法2:动态规划,时间复杂度为O(n^2)
     */
    public static boolean wordBreak(String s, List<String> wordDict) {
    	int len = s.length();
    	// 状态dp[i]表示前i个字符组成的字符串能否被字典中的word来组成。
    	// 状态转换方式:dp[i] = dp[0..j] &&  (s.sub(j.i) 是否由wordDict组成) 同时成立时,dp[i]=true
        // 动态规划dp[i]的值并不一定非得由dp[i-1]决定,也可以是受dp[0]..dp[i-1]值影响
    	Boolean[] dp = new Boolean[len + 1];
    	dp[0] = true;
    	for (int i = 1; i <= len; i++) {
    		dp[i] = false;
    		// 如果s[0..j) 是由wordDict 组成,并且 s[j..i]也由wordDict的某个单词构成
    		// 说明dp[i] 是可以由wordDict组成的
    		for (int j = 0; j < i; j++) {
    			if (dp[j] && wordDict.contains(s.substring(j, i))) {
    				dp[i] = true;
    				break;
    			}
    		}
    	}
    
    	return dp[len];
    }
    
    // 测试用例
    public static void main(String[] args) {
    	String s = "leetcode";
    	List<String> wordDict = new ArrayList<>();
    	// "leet", "code"
    	wordDict.add("leet");
    	wordDict.add("code");
    	boolean ans = wordBreak(s, wordDict);
    	System.out.println("demo01 result:" + ans);
    
    	s = "applepenapple";
    	wordDict = new ArrayList<>();
    	// ["apple", "pen"]
    	wordDict.add("apple");
    	wordDict.add("pen");
    	ans = wordBreak(s, wordDict);
    	System.out.println("demo02 result:" + ans);
    
    	s = "catsandog";
    	wordDict = new ArrayList<>();
    	//["cats", "dog", "sand", "and", "cat"]
    	wordDict.add("cats");
    	wordDict.add("dog");
    	wordDict.add("sand");
    	wordDict.add("and");
    	wordDict.add("cat");
    	ans = wordBreak(s, wordDict);
    	System.out.println("demo03 result:" + ans);
    }
    
  • 相关阅读:
    阶乘递归实现
    队列
    1+2+3+...+100用递归实现
    快速排序C语言实现
    js的onfocus,onblur事件
    CSP2021 游记 菜到离谱
    700题复习计划
    [传递闭包] P2881 [USACO07MAR]排名的牛Ranking the Cows
    【笔记】序列分块
    【题解】UVA10930 A-Sequence
  • 原文地址:https://www.cnblogs.com/fyusac/p/13194037.html
Copyright © 2011-2022 走看看