树的递归
104. 二叉树的最大深度
题目链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
递归
利用递归,我们可以很方便地求得最大深度。当前树的最大深度是左右子树的最大深度加1。时间复杂度为O(n),树的每个节点都要遍历一次。
int maxDepth(TreeNode* root) {
return root? 1 + max(maxDepth(root->left), maxDepth(root->right)): 0;
}
迭代
利用队列来模拟
/**
* 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 maxDepth(TreeNode* root) {
if(!root) return 0;
queue<TreeNode *> q;
q.push(root);
int res = 0;
while(!q.empty())
{
//n表示当前层有多少元素
int n = q.size();
while(n--)
{
//遍历当前层的所有元素,并把其左右节点压入队列中
TreeNode* tmp = q.front();
q.pop();
if(tmp -> left) q.push(tmp -> left);
if(tmp -> right) q.push(tmp -> right);
}
//一层+1
res++;
}
return res;
}
};
101. 对称二叉树
题目链接:https://leetcode-cn.com/problems/symmetric-tree/
递归
两个子树互为镜像当且仅当:
- 两个子树的根节点相等;
- 第一颗子树的左子树和第二颗子树的右子树互为镜像,且第一颗子树的右子树与第二颗子树的左子树互为镜像;
时间复杂度:O(n),每个节点都要遍历一遍
/**
* 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 isSymmetric(TreeNode* root) {
//根节点为空,为true
bool res = true;
if(root) res = isSym(root -> left, root -> right);
return res;
}
bool isSym(TreeNode* l, TreeNode* r)
{
//如果左右节点同时为空,则说明对称
if(!l && !r) return true;
//如果左右节点其中一个为空,则不是对称的
if(!l || !r) return false;
//如果做左节点的值不等于右节点的值,也不是对称的
if(l -> val != r -> val) return false;
//递归判断第一颗子树的左子树和第二颗子树的右子树
// 第一颗子树的右子树和第二颗子树的左子树
//.是否对称
return isSym(l -> left, r -> right) && isSym(l -> right, r -> left);
}
};
迭代
用队列模拟,依次将第左子树的左孩子,右子树的右孩子;左子树的右孩子,右子树的左孩子入队;迭代判断,相邻的两个节点应该相同。
/**
* 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 isSymmetric(TreeNode* root) {
//树为空,对称
if(root == NULL) return true;
queue<TreeNode*> q;
//先将左右子树依次入队
q.push(root -> left);
q.push(root -> right);
while(!q.empty())
{
//从队列中取出两个节点,进行比较
//左节点
TreeNode* l = q.front();
q.pop();
//右节点
TreeNode* r = q.front();
q.pop();
//都为空,继续往后判断
if(!l && !r) continue;
//其中一个为空,不对称
if(!l || !r) return false;
//二者值不相同,不对称
if(l -> val != r -> val) return false;
//第一颗树的左孩子与第二颗树的右孩子应该相同
//第一颗树的左孩子入队
q.push(l -> left);
//第二颗树的右孩子入队
q.push(r -> right);
//第一颗树的右孩子与第二颗树的左孩子应该相同
//第一颗树的右孩子入队
q.push(l -> right);
//第一颗树的左孩子入队
q.push(r -> left);
}
return true;
}
};
110. 平衡二叉树
题目链接:https://leetcode-cn.com/problems/balanced-binary-tree/
递归
根据平衡二叉树的定义:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。来进行判断。
/**
* 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 isBalanced(TreeNode* root) {
//根节点为空,平衡
if(!root) return true;
return abs(length(root -> left) - length(root -> right)) <= 1 && isBalanced(root -> left) && isBalanced(root -> right);
}
int length(TreeNode* root)
{
return root ? 1 + max(length(root -> left), length(root -> right)) : 0;
}
};
543. 二叉树的直径
题目链接:https://leetcode-cn.com/problems/diameter-of-binary-tree/
递归
路径的长度为节点数目减1,使用深度优先搜索,遍历二叉树,每次更新ans为max(ans, l + r + 1);
/**
* 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 = 1;
int diameterOfBinaryTree(TreeNode* root) {
dfs(root);
return ans - 1;
}
int dfs(TreeNode* root)
{
//空结点返回0
if(!root) return 0;
//左儿子为根的子树的深度
int l = dfs(root -> left);
//右儿子为根的子树的深度
int r = dfs(root -> right);
//更新ans
ans = max(ans, l + r + 1);
return max(l, r) + 1;
}
};
437. 路径总和Ⅲ
题目链接:https://leetcode-cn.com/problems/path-sum-iii/
递归
/**
* 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 pathSum(TreeNode* root, int sum) {
if (!root) return 0;
return dfs(root, sum) + pathSum(root->left, sum) + pathSum(root->right, sum);
}
int dfs(TreeNode* root, int sum)
{
if (nullptr == root) return 0;
sum -= root->val;
return (0 == sum ? 1 : 0) + dfs(root->left, sum) + dfs(root->right, sum);
}
};
非递归
class Solution
{
public:
int helper(TreeNode* root, int sum, vector<int>& path)
{
if (!root) return 0;
path.push_back(root->val);
int sum_cur = 0;
int res = 0;
for (int i= path.size()-1; i>=0; i--)
{
sum_cur+= path[i];
if (sum_cur == sum) ++res;
}
res += helper(root->left, sum, path) + helper(root->right, sum, path);
path.pop_back();
return res;
}
int pathSum(TreeNode* root, int sum)
{
vector<int> path;
return helper(root, sum, path);
}
};
34. 二叉树中和为某一值的路径(剑指offer)
题目链接:https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/
递归
使用深度优先搜索来完成,
/**
* 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<int> path;
vector<vector<int>> res;
vector<vector<int>> pathSum(TreeNode* root, int sum) {
dfs(root, sum);
return res;
}
void dfs(TreeNode* root, int sum)
{
if(!root) return ;
path.push_back(root->val);
sum -= root -> val;
//判断当前节点是不是叶子节点,并且是否满足sum=0
if(!root -> left && !root -> right && !sum) res.push_back(path);
//递归处理左右子树
dfs(root -> left, sum);
dfs(root -> right, sum);
//path还原
path.pop_back();
}
};
26. 树的子结构(剑指offer)
题目链接:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/
递归
从根节点开始递归判断B是不是A的子树
-
如果A或B为空,返回false;
-
如果以A当前节点为根节点的子树与B中节点均相同,返回true;
-
判断以A当前节点的左右节点的子树与B中节点均相同,有一个相同则为ture;
其中用到isSame函数判断两颗树的节点是否相同,递归进行判断:
B为空,表示遍历结束,满足条件,返回true
A节点为空或者A节点的值不等于B节点的值,返回false;
判断A的左子树与B的左子树,A的右子树与B的右子树是否相等
/** * 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 isSubStructure(TreeNode* A, TreeNode* B) { if(!A || !B) return false; if(isSame(A, B)) return true; return isSubStructure(A -> left, B) || isSubStructure(A -> right, B); } bool isSame(TreeNode *A ,TreeNode *B) { if(!B) return true; if(!A || A -> val != B -> val) return false; return isSame(A -> left, B->left) && isSame(A -> right, B -> right); } };
27. 二叉树的镜像(剑指offer)
题目链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/
队列
将根节点入队,从根节点开始,如果当前节点不空,交换当前节点的左右节点,并将左右节点依次入队;直到队列为空;
/**
* 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:
TreeNode* mirrorTree(TreeNode* root) {
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
TreeNode* node = q.front();
q.pop();
if (node == NULL) {
continue;
}
//交换两个左右节点
swap(node->left, node->right);
q.push(node->left);
q.push(node->right);
}
return root;
}
};
前中后序遍历
144. 前序遍历
题目链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
迭代实现:递归实质就是栈实现的,可以用栈来迭代模拟。注意入栈顺序
/**
* 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<int> preorderTraversal(TreeNode* root) {
vector<int> res;
//空树
if(!root) return res;
stack<TreeNode*> st;
//根节点入栈
st.push(root);
while(!st.empty())
{
auto node = st.top();
res.push_back(node -> val);
st.pop();
//右
if(node -> right) st.push(node -> right);
//左
if(node -> left) st.push(node -> left);
}
return res;
}
};
145. 后序遍历
题目链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/
指针
/**
* 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<int> postorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode *dummy = new TreeNode(-1);
dummy->left = root;
root = dummy;
while (root)
{
if (!root->left) root = root->right;
else
{
TreeNode *pre = root->left;
while (pre->right && pre->right != root) pre = pre->right;
if (pre->right)
{
pre->right = 0;
int top = res.size();
for (TreeNode *p = root->left; p; p = p->right)
res.push_back(p->val);
reverse(res.begin() + top, res.end());
root = root->right;
}
else
{
pre->right = root;
root = root->left;
}
}
}
return res;
}
};
队列
/**
* 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<int> postorderTraversal(TreeNode* root) {
deque<TreeNode*> d;
vector<int> res;
if(!root) return res;
d.push_front(root);
while(!d.empty())
{
TreeNode* cur = d.front();
res.push_back(cur -> val);
if(cur -> left) d.push_front(cur -> left);
if(cur -> right) d.push_front(cur -> right);
}
return res;
}
};
栈
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> res;
stack<TreeNode*> st;
if(root!=nullptr) st.push(root);
while(!st.empty())
{
TreeNode *t = st.top();
st.pop();
if(t!=nullptr)
{
st.push(t); //在右节点之前重新插入该节点,以便在最后处理(访问值)
st.push(nullptr); //nullptr跟随t插入,标识已经访问过,还没有被处理
if(t->right) st.push(t->right);
if(t->left) st.push(t->left);
}else
{
res.push_back(st.top()->val);
st.pop();
}
}
return res;
}
};
94. 中序遍历
题目链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> st;
if(root != nullptr) st.push(root);
while(!st.empty())
{
TreeNode *t = st.top();
st.pop();
if(t != nullptr)
{
if(t -> right) st.push(t -> right);
st.push(t); //在左节点之前重新插入该节点,以便在左节点之后处理(访问值)
st.push(nullptr); //nullptr跟随t插入,标识已经访问过,还没有被处理
if(t -> left) st.push(t -> left);
}else
{
res.push_back(st.top() -> val);
st.pop();
}
}
return res;
}
};
07. 重建二叉树(剑指offer)
题目链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/
递归建立整棵二叉树:先递归创建左右子树,然后创建根节点,并让指针指向两棵子树。
- 先利用前序遍历找根节点:前序遍历的第一个数,就是根节点的值;
- 在中序遍历中找到根节点的位置 k,则 k 左边是左子树的中序遍历,右边是右子树的中序遍历;
假设左子树的中序遍历的长度是 ll,则在前序遍历中,根节点后面的 ll 个数,是左子树的前序遍历,剩下的数是右子树的前序遍历; - 有了左右子树的前序遍历和中序遍历,我们可以先递归创建出左右子树,然后再创建根节点;
- 时间复杂度分析:我们在初始化时,用哈希表(unordered_map<int,int>)记录每个值在中序遍历中的位置,这样我们在递归到每个节点时,在中序遍历中查找根节点位置的操作,只需要 O(1)的时间。此时,创建每个节点需要的时间是 O(1),所以总时间复杂度是 O(n)。
/**
* 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:
unordered_map<int, int> pos;
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n = preorder.size();
//用哈希表(unordered_map<int,int>)记录每个值在中序遍历中的位置
for(int i = 0; i < n; i++)
pos[inorder[i]] = i;
return dfs(preorder, inorder, 0, n - 1, 0, n - 1);
}
TreeNode* dfs(vector<int>& pre, vector<int>& inor, int pl, int pr, int il, int ir)
{
if(pl > pr) return nullptr;
//在中序遍历中找到根节点的位置 k
int k = pos[pre[pl]] - il;
TreeNode* root = new TreeNode(pre[pl]);
root -> left = dfs(pre, inor, pl + 1, pl + k, il, il + k - 1);
root -> right = dfs(pre, inor, pl + k + 1, pr, il + k + 1, ir);
return root;
}
};
37. 序列化二叉树(剑指offer)
递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string res;
dfs_s(root, res);
return res;
}
void dfs_s(TreeNode *root, string& res)
{
if(!root){
res += "n ";
return ;
}
res += to_string(root -> val) + ' ';
dfs_s(root -> left, res);
dfs_s(root -> right, res);
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
int u = 0;
return dfs_d(u, data);
}
TreeNode* dfs_d(int &u, string data)
{
if(u == data.size()) return nullptr;
int k = u;
while(data[k] != ' ') k++;
if(data[u] == 'n'){
u = k + 1;
return nullptr;
}
int val = 0;
if(data[u] == '-'){
for(int i = u + 1; i < k; i++)
val = val * 10 + data[i] - '0';
val = -val;
}
else
{
for(int i = u; i < k; i++)
val = val * 10 + data[i] - '0';
}
u = k + 1;
auto root = new TreeNode(val);
root -> left = dfs_d(u, data);
root -> right = dfs_d(u, data);
return root;
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));
层次遍历
102. 二叉树的层序遍历
题目链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/submissions/
/**
* 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<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
//下一层的节点数目
int n = q.size();
vector<int> v;
for(int i = 0; i < n; i++)
{
auto node = q.front();
q.pop();
v.push_back(node -> val);
//将下一层的节点依次入队
if(node -> left) q.push(node -> left);
if(node -> right) q.push(node -> right);
}
res.push_back(v);
}
return res;
}
};
32-I. 从上到下打印二叉树(剑指offer)
题目链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/
/**
* 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<int> levelOrder(TreeNode* root) {
vector<int> res;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
TreeNode* tmp = q.front();
q.pop();
res.push_back(tmp->val);
if(tmp->left)
q.push(tmp->left);
if(tmp->right)
q.push(tmp->right);
}
return res;
}
};
32-II. 从上到下打印二叉树(剑指offer)
题目链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/
/**
* 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<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
vector<int> v;
int len = q.size();
while(len--)
{
TreeNode* tmp = q.front();
v.push_back(tmp->val);
q.pop();
if(tmp->left) q.push(tmp->left);
if(tmp->right) q.push(tmp->right);
}
res.push_back(v);
}
return res;
}
};
32-III. 从上到下打印二叉树(剑指offer)
题目链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/
/**
* 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<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root) return res;
deque<TreeNode*> q;
q.push_back(root);
int flag = 1;
while(!q.empty())
{
vector<int> v;
int len = q.size();
while(len--)
{
TreeNode* tmp;
if(flag == 1)
{
tmp = q.front();
q.pop_front();
v.push_back(tmp->val);
//顺序不能颠倒
if(tmp->left) q.push_back(tmp->left);
if(tmp->right) q.push_back(tmp->right);
}else
{
tmp = q.back();
q.pop_back();
if(tmp->right) q.push_back(tmp->right);
if(tmp->left) q.push_back(tmp->left);
}
}
flag = -flag;
res.push_back(v);
}
return res;
}
};
二叉搜索树BST
每个父节点,左节点的值小于父节点的值,右节点的值大于父节点的值;BST可以在O(nlogn)的时间内查找一个值是否存在:从根节点开始,若当前节点的值大于查找值则向左下走,若当前节点的值小于查找值则向右下走。同时因为二叉查找树是有序的,对其中序遍历的结果即为排好序的数组。
template <class T>
class BST
{
struct Node
{
T data;
Node* left;
Node* right;
};
Node* root;
Node* makeEmpty(Node* t)
{
if (t == NULL) return NULL;
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
return NULL;
}
Node* insert(Node* t, T x)
{
if (t == NULL)
{
t = new Node;
t->data = x;
t->left = t->right = NULL;
}
else if (x < t->data)
{
t->left = insert(t->left, x);
}
else if (x > t->data)
{
t->right = insert(t->right, x);
}
return t;
}
Node* find(Node* t, T x)
{
if (t == NULL) return NULL;
if (x < t->data) return find(t->left, x);
if (x > t->data) return find(t->right, x);
return t;
}
Node* findMin(Node* t)
{
if (t == NULL || t->left == NULL) return t;
return findMin(t->left);
}
Node* findMax(Node* t)
{
if (t == NULL || t->right == NULL) return t;
return findMax(t->right);
}
Node* remove(Node* t, T x)
{
Node* temp;
if (t == NULL) return NULL;
else if (x < t->data) t->left = remove(t->left, x);
else if (x > t->data) t->right = remove(t->right, x);
else if (t->left && t->right)
{
temp = findMin(t->right);
t->data = temp->data;
t->right = remove(t->right, t->data);
}
else
{
temp = t;
if (t->left == NULL) t = t->right;
else if (t->right == NULL) t = t->left;
delete temp;
}
return t;
}
public:
BST(): root(NULL) {}
~BST()
{
root = makeEmpty(root);
}
void insert(T x)
{
insert(root, x);
}
void remove(T x)
{
remove(root, x);
}
};
669. 修剪二叉搜索树
题目链接:https://leetcode-cn.com/problems/trim-a-binary-search-tree/
利用二叉查找树的大小关系,我们可以很容易地利用递归进行树的处理
1.如果大于R,则右枝都大于R,直接丢掉,递归左节点并返回;
2.如果小于L,则左枝都小于L,直接丢掉,递归右节点并返回;
3.否则分别递归处理左右节点,并返回当前节点。
时间复杂度:O(n) 空间复杂度:O(n)
/**
* 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:
TreeNode* trimBST(TreeNode* root, int L, int R)
{
if(!root) return root;
//如果根节点的值大于R, 丢弃整个左子树
if(root -> val > R) return trimBST(root -> left, L, R);
//如果根节点的值小于L, 丢弃整个右子树
if(root -> val < L) return trimBST(root -> right, L, R);
//如果根节点在区间内,递归处理左右节点
root -> left = trimBST(root -> left, L, R);
root -> right = trimBST(root -> right, L, R);
return root;
}
};
54. 二叉搜索树的第k个节点(剑指offer)
题目链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/
/**
* 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 kthLargest(TreeNode* root, int k) {
stack<TreeNode *> st;
int i = 0;
while(!st.empty() || root)
{
while(root)
{
st.push(root);
root = root -> right;
}
root = st.top();
st.pop();
i++ ;
if(i == k) return root->val;
root = root->left;
}
return 0;
}
};
36. 二叉搜索树与双向链表(剑指offer)
题目链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/submissions/
/*
// 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) {
root = treeToDoublyList(root, 0);
if(!root) return NULL;
Node* p = root;
while(p -> right) p = p -> right;
p -> right = root;
root -> left = p;
return root;
}
Node* treeToDoublyList(Node *root, int flag)
{
if(root == NULL) return NULL;
Node *left_ = treeToDoublyList(root -> left, 1);
Node *right_ = treeToDoublyList(root -> right, 0);
root -> left = left_;
root -> right = right_;
if(left_) left_ -> right = root;
if(right_) right_ -> left = root;
Node *p = root;
if(!flag) while(p -> left) p = p -> left;
else while(p -> right) p = p -> right;
return p;
}
};
68-I 二叉搜索树的最近公共祖先(剑指offer)
题目链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/
/**
* 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:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root) return nullptr;
while(root)
{
if(p -> val < root -> val && q -> val < root -> val) root = root -> left;
else if(p -> val > root -> val && q -> val > root -> val) root = root -> right;
else break;
}
return root;
}
};
68-II 二叉搜索树的最近公共祖先(剑指offer)
/**
* 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:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root) return NULL;
if(root == p||root == q) return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left && right) return root;
return left ? left : right; // 只有一个非空则返回该指针,两个都为空则返回空指针
}
};
33. 二叉搜索树的后续遍历序列(剑指offer)
题目链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/
class Solution {
public:
vector<int> seq;
bool verifyPostorder(vector<int>& postorder) {
seq = postorder;
return dfs(0, seq.size() - 1);
}
bool dfs(int l , int r)
{
if(l >= r) return true;
int root = seq[r];
int k = l;
while(k < r && seq[k] < root) k++;
for(int i = k; i < r; i++)
if(seq[i] < root) return false;
return dfs(l, k - 1) && dfs(k, r - 1);
}
};