剑指 Offer II 056. 二叉搜索树中两个节点之和
中序遍历+双指针
bst中序就是升序序列,然后双指针即可
class Solution {
public:
void get_nums(TreeNode* root, vector<TreeNode*> &nums){
if(!root) return;
get_nums(root->left, nums);
nums.emplace_back(root);
get_nums(root->right, nums);
}
bool findTarget(TreeNode* root, int k) {
vector<TreeNode*> nums;
get_nums(root,nums);
for(int i = 0, j = nums.size()-1; i < nums.size(); i++) {
while(j > i && nums[i]->val + nums[j]->val > k) j--;
if(j > i && nums[i]->val+nums[j]->val == k) return true;
}
return false;
}
};
dfs+哈希表
因为两个结点是相互的,所以不用担心还未遍历整个树就开始判断。
class Solution {
private:
unordered_set<int> us;
public:
bool findTarget(TreeNode* root, int k) {
if(!root) return false;
if(us.count(k-root->val)) return true;
us.insert(root->val);
return findTarget(root->left,k) || findTarget(root->right, k);
}
};
直接遍历导致时间复杂度为 O ( N 2 ) O(N^2) O(N2)
class MyCalendar {
public:
vector<pair<int,int>> ls;
MyCalendar() {
}
bool book(int start, int end) {
for(auto range: ls) {
if(range.first < end && start < range.second)
return false;
}
ls.push_back({start,end});
return true;
}
};
线段树优化
class MyCalendar {
unordered_set<int> tree, lazy;
public:
bool query(int start, int end, int l, int r, int idx) {
if (r < start || end < l) {
return false;
}
/* 如果该区间已被预订,则直接返回 */
if (lazy.count(idx)) {
return true;
}
if (start <= l && r <= end) {
return tree.count(idx);
}
int mid = (l + r) >> 1;
return query(start, end, l, mid, 2 * idx) ||
query(start, end, mid + 1, r, 2 * idx + 1);
}
void update(int start, int end, int l, int r, int idx) {
if (r < start || end < l) {
return;
}
if (start <= l && r <= end) {
tree.emplace(idx);
lazy.emplace(idx);
} else {
int mid = (l + r) >> 1;
update(start, end, l, mid, 2 * idx);
update(start, end, mid + 1, r, 2 * idx + 1);
tree.emplace(idx);
if (lazy.count(2 * idx) && lazy.count(2 * idx + 1)) {
lazy.emplace(idx);
}
}
}
bool book(int start, int end) {
if (query(start, end - 1, 0, 1e9, 1)) {
return false;
}
update(start, end - 1, 0, 1e9, 1);
return true;
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/fi9suh/solution/ri-cheng-biao-by-leetcode-solution-w06j/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
剑指 Offer II 057. 值和下标之差都在给定的范围内
滑动窗口+二分查找
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
set<int> st;
for(int i = 0; i < nums.size(); i++) {
auto it = st.lower_bound(max(nums[i],INT_MIN+t) - t); //防止key溢出int
if(it != st.end() && *it <= min(nums[i],INT_MAX-t) + t) {//防止key溢出int
return true;
}
st.insert(nums[i]);
if(i >= k) st.erase(nums[i-k]); //滑动窗口
}
return false;
}
};