【模拟面试】#9 实现 Trie (前缀树) 摘樱桃 最大二叉树 II
题目1
实现一个 Trie (前缀树),包含 insert
, search
, 和 startsWith
这三个操作。
示例:
Trie trie = new Trie();trie.insert("apple"); trie.search("apple"); // 返回 true trie.search("app"); // 返回 false trie.startsWith("app"); // 返回 true trie.insert("app"); trie.search("app"); // 返回 true
说明:
- 你可以假设所有的输入都是由小写字母
a-z
构成的。 - 保证所有输入均为非空字符串。
思路及代码
建树的过程,只不过这里一个节点可以有26个孩子,因为英文26个字母。然后叶子节点存一下string,来证明有这个值。
前缀的话只要搜索树,节点存在即可。
class Trie {
public:struct TrieNode{//孩子节点,分别记录26个字母struct TrieNode* children[26];//当前的节点(叶子节点)对应的单词string item;};TrieNode* root;/** Initialize your data structure here. */Trie() {root = new TrieNode(); }/** Inserts a word into the trie. */void insert(string word) {TrieNode* p = root;int len = word.size();for(int i = 0;i < len;i++){if(p->children[word[i] - 'a'] == NULL){p->children[word[i] - 'a'] = new TrieNode();}p = p->children[word[i] - 'a'];}p->item = word;}/** Returns if the word is in the trie. */bool search(string word) {TrieNode* p = root;int len = word.size();for(int i = 0;i < len;i++){if(p->children[word[i] - 'a'] == NULL){return false;}p = p->children[word[i] - 'a'];}return p->item == word;}/** Returns if there is any word in the trie that starts with the given prefix. */bool startsWith(string prefix) {TrieNode* p = root;int len = prefix.size();for(int i = 0;i < len;i++){if(p->children[prefix[i] - 'a'] == NULL){return false;}p = p->children[prefix[i] - 'a'];}return true;}
};/*** Your Trie object will be instantiated and called as such:* Trie* obj = new Trie();* obj->insert(word);* bool param_2 = obj->search(word);* bool param_3 = obj->startsWith(prefix);*/
题目2
一个N x N的网格(grid)
代表了一块樱桃地,每个格子由以下三种数字的一种来表示:
- 0 表示这个格子是空的,所以你可以穿过它。
- 1 表示这个格子里装着一个樱桃,你可以摘到樱桃然后穿过它。
- -1 表示这个格子里有荆棘,挡着你的路。
你的任务是在遵守下列规则的情况下,尽可能的摘到最多樱桃:
- 从位置 (0, 0) 出发,最后到达 (N-1, N-1) ,只能向下或向右走,并且只能穿越有效的格子(即只可以穿过值为0或者1的格子);
- 当到达 (N-1, N-1) 后,你要继续走,直到返回到 (0, 0) ,只能向上或向左走,并且只能穿越有效的格子;
- 当你经过一个格子且这个格子包含一个樱桃时,你将摘到樱桃并且这个格子会变成空的(值变为0);
- 如果在 (0, 0) 和 (N-1, N-1) 之间不存在一条可经过的路径,则没有任何一个樱桃能被摘到。
示例 1:
输入: grid = [[0, 1, -1],[1, 0, -1],[1, 1, 1]] 输出: 5 解释: 玩家从(0,0)点出发,经过了向下走,向下走,向右走,向右走,到达了点(2, 2)。 在这趟单程中,总共摘到了4颗樱桃,矩阵变成了[[0,1,-1],[0,0,-1],[0,0,0]]。 接着,这名玩家向左走,向上走,向上走,向左走,返回了起始点,又摘到了1颗樱桃。 在旅程中,总共摘到了5颗樱桃,这是可以摘到的最大值了。
说明:
grid
是一个N
*N
的二维数组,N的取值范围是1 <= N <= 50
。- 每一个
grid[i][j]
都是集合{-1, 0, 1}
其中的一个数。 - 可以保证起点
grid[0][0]
和终点grid[N-1][N-1]
的值都不会是 -1。
思路及代码
用DP的,难题,不是很懂,这篇题解看完后,列下方程能够理解了,但是代码还是写不出来ORZ
直接贴题解:https://leetcode-cn.com/problems/cherry-pickup/solution/dong-tai-gui-hua-xiang-xi-jie-xi-tu-jie-by-newhar/
class Solution {
public:int cherryPickup(vector<vector<int>>& grid) {int N = grid.size(), dp[N+1][N+1];memset(dp, 0x80, sizeof(dp)); //-2139062144, 作用相当于 INT_MINdp[N-1][N-1] = grid[N-1][N-1]; // 初始边界条件for(int sum = 2*N - 3; sum >= 0; --sum)for(int i1 = max(0, sum - N + 1); i1 <= min(N-1,sum); ++i1)for(int i2 = i1; i2 <= min(N-1,sum); ++i2){int j1 = sum - i1, j2 = sum - i2;if(grid[i1][j1] == -1 || grid[i2][j2] == -1) dp[i1][i2] = INT_MIN;elsedp[i1][i2] = grid[i1][j1] + (i1 != i2 || j1 != j2)*grid[i2][j2] + max(max(dp[i1][i2+1], dp[i1+1][i2]), max(dp[i1+1][i2+1], dp[i1][i2]));}return max(0, dp[0][0]);}
};
题目3
最大树定义:一个树,其中每个节点的值都大于其子树中的任何其他值。
给出最大树的根节点 root
。
就像之前的问题那样,给定的树是从表 A
(root = Construct(A)
)递归地使用下述 Construct(A)
例程构造的:
- 如果
A
为空,返回null
- 否则,令
A[i]
作为 A 的最大元素。创建一个值为A[i]
的根节点root
root
的左子树将被构建为Construct([A[0], A[1], ..., A[i-1]])
root
的右子树将被构建为Construct([A[i+1], A[i+2], ..., A[A.length - 1]])
- 返回
root
请注意,我们没有直接给定 A,只有一个根节点 root = Construct(A)
.
假设 B
是 A
的副本,并附加值 val
。保证 B
中的值是不同的。
返回 Construct(B)
。
示例 1:
输入:root = [4,1,3,null,null,2], val = 5 输出:[5,4,null,1,3,null,null,2] 解释:A = [1,4,2,3], B = [1,4,2,3,5]
示例 2:
输入:root = [5,2,4,null,1], val = 3 输出:[5,2,4,null,1,null,3] 解释:A = [2,1,5,4], B = [2,1,5,4,3]
示例 3:
输入:root = [5,2,3,null,1], val = 4 输出:[5,2,4,null,1,3] 解释:A = [2,1,5,3], B = [2,1,5,3,4]
提示:
1 <= B.length <= 100
思路及代码
比根节点要大,直接在当前这里新建节点了,否则向右递归
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* insertIntoMaxTree(TreeNode* root, int val) {if(root == NULL){return new TreeNode(val);}else{if(root->val < val){TreeNode* _root = new TreeNode(val);_root->left = root;return _root;}else{TreeNode* _right = insertIntoMaxTree(root->right, val);root->right = _right;return root;}}}
};
【模拟面试】#9 实现 Trie (前缀树) 摘樱桃 最大二叉树 II相关推荐
- LeetCode 208. 实现 Trie (前缀树) —— 提供一套前缀树模板
208. 实现 Trie (前缀树) Ideas 前缀树嘛,直接套模板咯,把之前写的拿过来抄一遍. 提供一下我的模板. Code Python class TrieNode:def __init__( ...
- leetcode 676. Implement Magic Dictionary | 676. 实现一个魔法字典(DFS+Trie 前缀树)
题目 https://leetcode.com/problems/implement-magic-dictionary/description/ 题解 题意理解 前缀树问题,大意是是让你在字典中找到是 ...
- leetcode 677. Map Sum Pairs | 677. 键值映射(Trie前缀树,BFS)
题目 https://leetcode.com/problems/map-sum-pairs/ 题解 基于前缀树实现,可以参考:leetcode 208. Implement Trie (Prefix ...
- 208. 实现 Trie (前缀树)
208. 实现 Trie (前缀树) Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键.这一数据结构有相当多的应用情景,例 ...
- leetcode208. 实现 Trie (前缀树)
实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie(); trie.insert(" ...
- Leetcode —— 208. 实现 Trie (前缀树)(Python)
实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie();trie.insert(" ...
- 【LeetCode】【HOT】208. 实现 Trie (前缀树)
[LeetCode][HOT]208. 实现 Trie (前缀树) 文章目录 [LeetCode][HOT]208. 实现 Trie (前缀树) package hot;public class So ...
- leetcode前缀树java_Java实现 LeetCode 208 实现 Trie (前缀树)
208. 实现 Trie (前缀树) 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie() ...
- 实现 Trie (前缀树)
题目描述 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie(); trie.insert( ...
最新文章
- 验证mongodb副本集并实现自动切换primary~记录过程
- 转载:JQuery制作的选项卡改进版
- 如何复制静态文件以使用Webpack构建目录?
- c++中两个类互相引用的问题
- Vue Router的集中统一管理
- mysql数据库2013_MySQL数据库备份(2)2013-6-13
- leetcode413. 等差数列划分(动态规划)
- 用 Excel+VBA 与 SQL Server 数据库交互
- 2021年浙江省高考成绩查询哪里快,2021年浙江高考成绩排名及成绩公布时间什么时候出来...
- Intel Sandy Bridge/Ivy Bridge架构/微架构/流水线 (2) - 流水线概述框图
- 网校网络工程师视频下载
- C 语言常见 API(fprintf、fputs、fprintf)
- 面向对象——私有成员
- python开发怎么成长_Python开发者四大进阶攻略,菜鸟的成神之路
- linux 查询命令 批量替换多个文件
- 01.ZooKeeper安装和介绍
- 聊聊论文分区,SCI,JCR,CCF分区你弄懂了吗?
- 1+X云计算平台运维与开发认证(初级)样卷C
- [病毒木马] LSP劫持
- 用递归调用函数来把存在父子级别的数据封装成一个树状结构
热门文章
- 永久删除的文件如何恢复
- Android开发技术总结!万字Android技术类校招面试题汇总,架构师必备技能
- SQL学习收获与心得
- HLS 流传输库hls::stream
- Folder Factory for mac(Mac文件夹图标修改软件)
- C++57个入门知识点_40 常成员函数(用于定义不可修改类内部成员变量的函数,一般用来修饰Get函数;常成员函数this指针:const T* const;常成员函数内部变量修改方法:强转/关键字)
- Ant Buster蚂蚁大作战(塔防类游戏经典)
- 分布式ID详解(5种分布式ID生成方案)
- 网络编程懒人入门(十一):一文读懂什么是IPv6
- JDK配置环境变量的意义