【Leetcode & Java】#面试题17.13 / 309
2021-04-17 10:27
标签:head 还需要 需要 $$ div 单词 数组 als code 这道题真的是要搞死我了…… 先来搞简单的部分—— 动态规划。 令 \(dp[i]\) 表示句子里前 i 个字符中最少的未识别字符数,此处前 i 个字符对应的是字符串 \(sentence.substring(0, i)\) ,也就是由第 0 ~ i - 1 个字符组成的字符串。当我们用字典中的词条去切割句子获得单词时,剩下没有成词的字符就是所有的未识别字符。由于不能确定哪种切割方式能留下最少的未识别字符,所以在求 \(dp[i]\) 时,需要遍历第 i 个字符前面所有的字符,来比较在哪一处切割能获得最小值。用 j 来表示最后一次成词时的切割位置( \(0 ),如果 \(sentence.substring(j, i)\) 是字典中的单词,则 \(dp[j]\) (前 j 个字符的最少的未识别字符数)是 \(dp[i]\) 的一个候选值。 \(dp[i]\) 的默认值为 $$dp[i] = dp[i-1] + 1$$ ,可以看作是第 i - 1 个字符无法与前面的字符组合成词时的情况。此外,因为所求为最小值,所以如果当前字符串 \(sentence.substring(j, i)\) 不能组成单词,\(dp[j] + i - j\) 肯定大于或等于 \(dp[i-1] + 1\) ,不会是最小值候补,无需考虑。 考虑 \(dp[0]\) 的情况。显然,\(dp[0] = 0\),用来表示 sentence 中字符数为 0 或还未开始遍历时未识别字符数为 0 。 动态规划部分的代码如下: 接下来需要解决的问题就是如何存储 & 查询字典中的词条。此处采用的是字典树 trie 的方式。 本质上,字典树将单词中的每一个字符当作一个节点存储在树中。假定单词中只包含小写字母,则理论上一个节点可以后接26个子节点。在二叉树中,我们可以用 node.left 和 node.right 来表示左右子节点,但在字典树中,如果类似地用 26 个字母来表示子节点就太繁琐太复杂了。为了方便表示,我用了哈希表来存储子节点(也可以用数组或者其他map 结构),其中 Key 值表示子节点对应的字符(可以理解为二叉树中的 node.val),Value 值表示字符对应的子节点。 还需要注意的是,在二叉树中,想要判断当前节点是否为叶子节点,方法是检查当前节点的左右子节点是否均为空,但这种做法并不能解决字典树中如何判断是否检索到词尾的问题。举例来说,假设词典中存有 "fun", "funny" 两个词,如何判断词典中收录了 "fun"? 如果还是用有无子节点来判断,显然是不正确的。所以需要一个属性来判断当前节点是否为一个单词的词尾,也就是代码中的 TrieNode.isWord. 字典树 TrieNode 的代码实现如下: 在本题中,需要实现字典树的插入和查找操作。首先,要将题目给出的 String[] dictionary 插入到字典中。其实这个 add 函数不难写,只是因为子节点使用 HashMap 表示的,所以需要搞清楚如何在哈希表中查询/插入节点(字符)。最后也不要忘记将词尾处的 isWord 的值改为 true。 字典组建完毕后,就需要实现用于动态规划部分的查找操作了。查找的思路其实和插入是一致的,都是检查:【1】当前字符是否为树中当前节点的子节点【2】词尾处的 isWord 的值,此处就不赘述了。 最后给出完整代码:
刷 leetcode 这些天已经遇到了不少动态规划的题。这一道中等难度的题算是一道质检吧。这道题看起来很复杂,但如果套用到动态规划的思路中,就可以顺利地解决了。 在本题中,我们要求解在最后一天结束后,所能获得的累计最大利润。首先,需要分析出在第 i 天结束后,共有几种可能的状态。根据题意,一共有 3 种可能: 分别用 \(dp[i][0], dp[i][1], dp[i][2]\) 来表示在第 i 天结束后,且处于上述 3 种对应状态时所积累的最大利润。根据分析,可以得到状态转移方程为: 得到状态转移方程后,考虑边界情况。显然,当 \(i = 0\) 时, 若不执行买入操作,那么累计的最大利润默认值为 0;若执行买入操作,最大利润需要在默认值基础上减去当天的股票价格。因此,当 \(i = 0\) 时,各状态的初始值为: 至此,基本解题思路已完成。但在观察状态转移方程时,可以发现 \(dp[i][...]\) 的值只和第 i-1 天的结果有关。因此,可以使用动态数组来降低 dp 数组维度,实现空间优化。 具体代码如下: 【Leetcode & Java】#面试题17.13 / 309 标签:head 还需要 需要 $$ div 单词 数组 als code 原文地址:https://www.cnblogs.com/zz123333/p/13303076.html
面试题 17.13 恢复空格【200709每日一题】
方法:字典树trie + 动态规划
int n = sentence.length();
int[] dp = new int[n + 1];
dp[0] = 0;
for(int i = 1; i
class TrieNode{
// 字典树
public boolean isWord;
// 感觉官方题解里面用 isEnd 表示更贴切
public Map
public void add(String word, TrieNode root){
// 插入新词
TrieNode current = root;
// 根节点不表示任何字符,首字母应在 root.next 的 map 中查找
int n = word.length();
for(int i = 0; i 没有这个字符
// 在 current.next 这个 map 中添加当前字符 --> 添加
// 此处应创建新的空白节点,等待添加后续字符
current.next.put(c, new TrieNode());
}
// 后移 current 至当前字符对应的节点
// 为了便于理解,此处类比二叉树中 node = node.left 的写法
// 实际可以直接写成 current = next;
current = current.next.get(c);
}
if(!current.isWord){
current.isWord = true;
}
}
public boolean inTrie(String word, TrieNode root){
// 查看 word 是否已在树中
TrieNode current = root;
int n = word.length();
for(int i = 0; i
class Solution {
public int respace(String[] dictionary, String sentence) {
int n = sentence.length();
int[] dp = new int[n + 1];
dp[0] = 0;
TrieNode root = new TrieNode();
if(n != 0){
for(int i = 0; i next;
// 也可以令 next 为数组形式
TrieNode(){
isWord = false;
//只有在当前字符为单词结尾时才令该值为真
next = new HashMap();
}
public void add(String word, TrieNode root){
// 插入新词
TrieNode current = root;
int n = word.length();
for(int i = 0; i 没有这个字符
// 在 current.next 这个 map 中添加当前字符 --> 添加
// 此处应创建新的空白节点,等待添加后续字符
current.next.put(c, new TrieNode());
}
//后移 current 至当前字符对应的节点
current = current.next.get(c);
// 可以简写成 current = next;
}
if(!current.isWord){
current.isWord = true;
}
}
public boolean inTrie(String word, TrieNode root){
// 查看 word 是否已在树中
TrieNode current = root;
int n = word.length();
for(int i = 0; i
本题中只涉及字典树的插入/查找操作,这篇文章还给出了字典树删除操作的实现方法,对字典树的讲解非常详细,五星好评:-)309.最佳买卖股票时机含冷冻期【200710每日一题】
方法:动态规划
--> 可能是第 i 天买入的(则第 i-1 天结束后必处于状态 3),也可能是继承了第 i-1 天持有的股票;
--> 第 i 天卖出了手中的股票,所以第 i-1 天必然持有股票;
--> 第 i 天没有执行买卖操作,且第 i-1 天也不持有股票,但不一定是在第 i - 1 天卖出的.class Solution {
public int maxProfit(int[] prices) {
int[] dp = new int[3];
if(prices.length > 0){
dp[0] = -prices[0];
dp[1] = 0;
dp[2] = 0;
}
for(int i = 1; i
文章标题:【Leetcode & Java】#面试题17.13 / 309
文章链接:http://soscw.com/index.php/essay/76071.html