• 【LeetCode每日一题】2020.6.25 139. 单词拆分


    139. 单词拆分

    给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

    说明:

    拆分时可以重复使用字典中的单词。
    你可以假设字典中没有重复的单词。

    示例:

    输入: s = "leetcode", wordDict = ["leet", "code"]
    输出: true
    解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。

    输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
    输出: false

    分析:

    ​ (1)匹配单词可以想到使用哈希表来存储 单词/布尔值 键值对来表示该字符串是否是wordDict中的单词。

    ​ (2)思考如何将s进行分隔,以便使用哈希表查询真值。可以使用动态规划来解决这个问题。dp[i] = true 表示s的前i个字符可以被wordDict中的单词匹配(注意:可以是一个单词,也可以是多个单词)。转移方程可以帮我们解决匹配多个单词的问题:(dp[i] = dp[j] && wordDictSet[s[i:j]])

    代码(Golang):

    func wordBreak(s string, wordDict []string) bool {
    	wordDictSet := make(map[string]bool)
    	for _, word := range wordDict {
    		wordDictSet[word] = true
    	}
    	dp := make([]bool, len(s) + 1)
    	dp[0] = true
    	for i := 1; i < len(s) + 1; i++ {
    		for j := 0; j < i; j++ {
    			if dp[j] && wordDictSet[s[j:i]] {
    				dp[i] = true
    				break
    			}
    		}
    	}
    	return dp[len(s)]
    }
    

    小结:

    ​ 这道题中使用了动态规划,就可以将一个看起来不好入手的问题分解成几个简单的问题:

    1. 确定字符串的一部分是否匹配成功。

    2. 将这部分字符串的真值 状态传递下去。

    3. 包含这部分字符串的大字符串的状态由小字符串 及 另一部分小字符串的状态决定。

    4. 大的字符串的状态又被转移到更大的字符串。

      做完之后思考这道题的解题步骤,再次感叹动态规划思想的精妙。


  • 相关阅读:
    POJ 1018 Communication System
    POJ 1017 Packets
    Codeforces 725B Food on the Plane
    Lessons learned from manually classifying CIFAR-10
    CCF推荐国际学术期刊
    局部数组过大导致编译栈区溢出问题
    自己动手写处理器之第一阶段(3)——MIPS32指令集架构简单介绍
    C++学习笔记29,引用变量(1)
    Android视频应用去广告学习实践
    sublime编辑器怎样高速输入PHP头部版本号声明
  • 原文地址:https://www.cnblogs.com/enmac/p/13192262.html
Copyright © 2020-2023  润新知