1. 二叉搜索树的第k大节点
给定一棵二叉搜索树,请找出其中第 k
大的节点的值。
Example 1
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 4
Example 2
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 4
Constraints:
- 1 ≤ k ≤ 二叉搜索树元素个数
代码 [反中序遍历]
class Solution {
public:
int kthLargest(TreeNode *root, int k) {
stack<TreeNode *> st;
TreeNode *cur = root;
while (cur || !st.empty()) {
if (cur) {
st.push(cur);
cur = cur->right;
} else {
cur = st.top();
st.pop();
if (--k == 0) return cur->val;
cur = cur->left;
}
}
return -1;
}
};
2. 二叉搜索树中的插入操作
给定二叉搜索树(BST)的根节点 root
和要插入树中的值 value
,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。
注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。
Example 1
输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]
Example 2
输入:root = [40,20,60,10,30,50,70], val = 25
输出:[40,20,60,10,30,50,70,null,null,25]
Constraints:
- 树中的节点数将在
[0, 10^4]
的范围内。 -10^8 <= Node.val <= 10^8
- 所有值
Node.val
是 独一无二 的。 -10^8 <= val <= 10^8
- 保证
val
在原始BST中不存在。
代码
class Solution {
public:
TreeNode *insertIntoBST(TreeNode *root, int val) {
if (!root) return new TreeNode(val);
TreeNode *node = root;
while (node) {
if (node->val < val) {
if (!node->right) {
node->right = new TreeNode(val);
return root;
}
node = node->right;
} else {
if (!node->left) {
node->left = new TreeNode(val);
return root;
}
node = node->left;
}
}
return root;
}
};
class Solution {
public:
TreeNode *insertIntoBST(TreeNode *root, int val) {
if (!root) return new TreeNode(val);
TreeNode *cur = root, *prev;
while (cur) {
prev = cur;
cur = val < cur->val ? cur->left : cur->right;
}
val < prev->val ? prev->left = new TreeNode(val) : prev->right = new TreeNode(val);
return root;
}
};
3. 合法二叉搜索树
实现一个函数,检查一棵二叉树是否为二叉搜索树。
Example 1
输入:
2
/ \
1 3
输出: true
Example 2
输入:
5
/ \
1 4
/ \
3 6
输出: false
代码
class Solution {
public:
bool isValidBST(TreeNode* root) {
stack<TreeNode*> st;
auto cur=root;
int prev=INT_MIN, flag=1;
while(cur||!st.empty()){
if(cur){
st.push(cur);
cur=cur->left;
}else{
cur=st.top();
st.pop();
if(cur->val<=prev&&flag==0) return false;
prev=cur->val;
flag=0;
cur=cur->right;
}
}
return true;
}
};
4. Range 模块
A Range Module is a module that tracks ranges of numbers. Design a data structure to track the ranges represented as half-open intervals and query about them.
A half-open interval [left, right)
denotes all the real numbers x
where left <= x < right
.
Implement the RangeModule
class:
RangeModule()
Initializes the object of the data structure.void addRange(int left, int right)
Adds the half-open interval[left, right)
, tracking every real number in that interval. Adding an interval that partially overlaps with currently tracked numbers should add any numbers in the interval[left, right)
that are not already tracked.boolean queryRange(int left, int right)
Returnstrue
if every real number in the interval[left, right)
is currently being tracked, andfalse
otherwise.void removeRange(int left, int right)
Stops tracking every real number currently being tracked in the half-open interval[left, right)
.
Example 1
Input
["RangeModule", "addRange", "removeRange", "queryRange", "queryRange", "queryRange"]
[[], [10, 20], [14, 16], [10, 14], [13, 15], [16, 17]]
Output
[null, null, null, true, false, true]
Explanation
RangeModule rangeModule = new RangeModule();
rangeModule.addRange(10, 20);
rangeModule.removeRange(14, 16);
rangeModule.queryRange(10, 14); // return True,(Every number in [10, 14) is being tracked)
rangeModule.queryRange(13, 15); // return False,(Numbers like 14, 14.03, 14.17 in [13, 15) are not being tracked)
rangeModule.queryRange(16, 17); // return True, (The number 16 in [16, 17) is still being tracked, despite the remove operation)
Constraints:
1 <= left < right <= 10^9
- At most
10^4
calls will be made toaddRange
,queryRange
, andremoveRange
.
代码 [线段树]
属于是,模板拿来就用的题目。
struct SegNode {
int l, r, sum, lazy;
SegNode *left, *right;
SegNode() {}
SegNode(int l, int r) : l(l), r(r), sum(0), lazy(0), left(nullptr), right(nullptr) {}
};
class RangeModule {
public:
SegNode *ST;
//-------------- SegmentTree start ------------//
SegNode *get_left(SegNode *rt) {
if (rt->left == nullptr) {
int mid = rt->l + ((rt->r - rt->l) >> 1);
rt->left = new SegNode(rt->l, mid);
}
return rt->left;
}
SegNode *get_right(SegNode *rt) {
if (rt->right == nullptr) {
int mid = rt->l + ((rt->r - rt->l) >> 1);
rt->right = new SegNode(mid + 1, rt->r);
}
return rt->right;
}
void push_up(SegNode *rt) { rt->sum = get_left(rt)->sum + get_right(rt)->sum; }
void push_down(SegNode *rt) {
if (rt->lazy != 0) {
int v = rt->lazy;
SegNode *ll = get_left(rt), *rr = get_right(rt);
ll->lazy = v;
rr->lazy = v;
if (v == 1) {
ll->sum = (ll->r - ll->l + 1);
rr->sum = (rr->r - rr->l + 1);
} else if (v == -1) {
ll->sum = 0;
rr->sum = 0;
}
rt->lazy = 0;
}
}
void update(SegNode *rt, int ul, int ur, int val) {
if (ul <= rt->l && rt->r <= ur) {
rt->lazy = val;
rt->sum = val == 1 ? rt->r - rt->l + 1 : 0;
return;
}
int mid = rt->l + ((rt->r - rt->l) >> 1);
SegNode *ll = get_left(rt), *rr = get_right(rt);
push_down(rt);
if (ur <= mid) {
update(ll, ul, ur, val);
} else if (mid + 1 <= ul) {
update(rr, ul, ur, val);
} else {
update(ll, ul, ur, val);
update(rr, ul, ur, val);
}
push_up(rt);
}
int query(SegNode *rt, int ql, int qr) {
if (ql <= rt->l && rt->r <= qr) {
return rt->sum;
}
int mid = (rt->l + rt->r) / 2;
SegNode *ll = get_left(rt);
SegNode *rr = get_right(rt);
push_down(rt);
if (qr <= mid) {
return query(ll, ql, qr);
} else if (mid + 1 <= ql) {
return query(rr, ql, qr);
}
return query(ll, ql, qr) + query(rr, ql, qr);
}
//--------------- SegmentTree end -------------//
RangeModule() { ST = new SegNode(0, (int) 1e9); }
void addRange(int left, int right) { update(ST, left, right - 1, 1); }
bool queryRange(int left, int right) { return query(ST, left, right - 1) == (right - left); }
void removeRange(int left, int right) { update(ST, left, right - 1, -1); }
};