题目
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
示例 1:
示例 2:
输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false
提示:
1 <= board.length <= 200 1 <= board[i].length <= 200 board 和 word
仅由大小写英文字母组成
来源:力扣(LeetCode)
链接:
代码
class Solution {
public:
bool exist(vector<vector<char>>& board, string word) {
rows = board.size();
cols = board[0].size();
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
if(dfs(board, word, i, j, 0)) return true;
}
}
return false;
}
private:
int rows, cols;
bool dfs(vector<vector<char>>& board, string word, int i, int j, int k) {
if(i >= rows || i < 0 || j >= cols || j < 0 || board[i][j] != word[k]) return false;
if(k == word.size() - 1) return true;
board[i][j] = '\0';
bool res = dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i - 1, j, k + 1) ||
dfs(board, word, i, j + 1, k + 1) || dfs(board, word, i , j - 1, k + 1);
board[i][j] = word[k];
return res;
}
};
题目
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:[]
示例 3:
输入:root = [1,2], targetSum = 0
输出:[]
提示:
树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
来源:力扣(LeetCode)
链接:
代码
class Solution {
public:
vector<vector<int>> ret;
vector<int> path;
void dfs(TreeNode* root, int target) {
if (root == nullptr) {
return;
}
path.emplace_back(root->val);
target -= root->val;
if (root->left == nullptr && root->right == nullptr && target == 0) {
ret.emplace_back(path);
}
dfs(root->left, target);
dfs(root->right, target);
path.pop_back();
}
vector<vector<int>> pathSum(TreeNode* root, int target) {
dfs(root, target);
return ret;
}
};
题目
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
为了让您更好地理解问题,以下面的二叉搜索树为例:
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
来源:力扣(LeetCode)
链接:
分析
由上面的例子可以看出,链表元素的排列是树按照左侧优先的中序遍历得到的,所以首先能够确定树的遍历要使用中序遍历。然后我们来观察双向链表的构成——每向后面新增一个结点只需要把他和最后一个结点相连,所以我们只需要在深度优先遍历的过程中记录上一个结点即可。最后我们要考虑如何连接,这里很显然要考虑双向链表的前结点和后结点,以及二叉树的左节点和右节点,我们不妨假设以及存在一个由二叉树遍历得到的部分的双向链表,最后一个结点为pre,那么pre的前结点已经连接上了,二叉树层序遍历的下一个结点应该与他相连。所以这时只需要确定二叉树的哪一个结点作为前结点即可确定后结点(因为只有两个结点,非前即后)。由于我们使用的是线序遍历,这就意味着当遍历到当前结点时,当前结点的所有子树全被遍历完了,即已经连接到双向链表之中了,这时当前结点的左节点所指向的结点已经在存在于双向链表,并且不会再被遍历到了,所有左节点为前结点。注意最后要将最后一个结点和首结点相连。
代码
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node() {}
Node(int _val) {
val = _val;
left = NULL;
right = NULL;
}
Node(int _val, Node* _left, Node* _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
public:
Node* treeToDoublyList(Node* root) {
if(root == nullptr) return nullptr;
dfs(root);
head->left = pre;
pre->right = head;
return head;
}
private:
Node *pre, *head;
void dfs(Node* cur) {
if(cur == nullptr) return;
dfs(cur->left);
if(pre != nullptr) pre->right = cur;
else head = cur;
cur->left = pre;
pre = cur;
dfs(cur->right);
}
};
题目
给定一棵二叉搜索树,请找出其中第 k 大的节点的值。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 4
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 4
限制:
1 ≤ k ≤ 二叉搜索树元素个数
来源:力扣(LeetCode)
链接:
分析
因为这是一棵搜索树,所以根结点比左节点大,比右节点小,根据这一性质使用中序遍历即可,注意根据k进行剪枝
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int ans;
void dfs(TreeNode* root, int k, int & cnt, int & ans){
if(cnt > k){
return;
}
if(root->right)
dfs(root->right, k, cnt, ans);
cnt++;
if(cnt==k){
ans=root->val;
return;
}
if(root->left)
dfs(root->left, k, cnt, ans);
}
int kthLargest(TreeNode* root, int k) {
int cnt=0;
if(root->right)
dfs(root->right, k, cnt, ans);
cnt++;
if(cnt==k){
ans=root->val;
return ans;
}
if(root->left)
dfs(root->left, k, cnt, ans);
return ans;
}
};
题目
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
来源:力扣(LeetCode)
链接:
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int n=0;
void dfs(TreeNode* root, int cur){
n = max(n, cur);
if(root->left != NULL){
dfs(root->left, cur+1);
}
if(root->right != NULL){
dfs(root->right, cur+1);
}
}
int maxDepth(TreeNode* root) {
if(root == NULL){
return 0;
}
dfs(root, 1);
return n;
}
};
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1
/ \
2 2
/ \
3 3
/ \
4 4
返回 false 。
来源:力扣(LeetCode)
链接:
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool dfs(TreeNode* root, int &cur){
if(root == NULL){
return true;
}
cur++;
int a, b;
a = b = cur;
bool flag1, flag2;
flag1 = dfs(root->left, a);
flag2 = dfs(root->right, b);
cur = max(a, b);
return flag1 && flag2 && abs(a-b) <= 1;
}
bool isBalanced(TreeNode* root) {
int cur=0;
return dfs(root, cur);
}
};
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
示例 1:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点 5
和节点 1 的最近公共祖先是节点 3。
示例 2:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点 5
和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。
说明:
所有节点的值都是唯一的。 p、q 为不同节点且均存在于给定的二叉树中。
来源:力扣(LeetCode)
链接:
分析
通过深度优先搜索找到p和q的路径,再按照路径比较即可,同时要注意当两个路径都找出来之后可以直接退出,用这个进行剪枝可以加快搜索。
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<TreeNode*> path_p, path_q;
void dfs(TreeNode* root, TreeNode* p, TreeNode* q, vector<TreeNode*> &v){
if(path_p.size() && path_q.size()){
return;
}
if(p == root){
path_p = v;
}
if(q == root){
path_q = v;
}
if(root->left != NULL){
v.push_back(root->left);
dfs(root->left, p, q, v);
v.pop_back();
}
if(root->right != NULL){
v.push_back(root->right);
dfs(root->right, p, q, v);
v.pop_back();
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*> v;
if(root){
v.push_back(root);
dfs(root, p, q, v);
}
TreeNode* ans;
for(int i=0; i < path_p.size() && i < path_q.size(); i++){
if(path_p[i] == path_q[i]){
ans=path_p[i];
}else{
break;
}
}
return ans;
}
};
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ovod.cn 版权所有 湘ICP备2023023988号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务