• 剑指offer专项突击版第19天


    剑指 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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    剑指 Offer II 058. 日程表

    直接遍历导致时间复杂度为 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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    线段树优化

    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)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    剑指 Offer II 057. 值和下标之差都在给定的范围内

    滑动窗口+二分查找

    • 由于下标差不能超过 k k k ,所以使用滑动窗口来限制窗口内元素个数为 k + 1 k+1 k+1 个。
    • 其次要满足滑动窗口内存在两元素差值小于等于 t t t ,假设当前的元素为 x x x ,那么就只需要在窗口内找到一个数在 [ x − t , x + t ] [x-t, x+t] [xt,x+t] 范围内。
    • x x x 右边的元素就不管了?只要右边的元素会跟 x x x 在同个窗口那么它就会考虑到 x x x ,而不用 x x x 来考虑。
    • 由于序列是无序的,如果直接找需要 O ( n k ) O(nk) O(nk) 会TLE,这里就需要只用set来动态维护序列有序性,并且二分快速找到大于等于 x − t x-t xt 的数集中最小的元素,然后判断这个元素是否<= x + t x+t x+t
    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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    实战项目如何抵御即跨站脚本(XSS)攻击
    【星海出品】C++的基础(一)理论知识
    el-table实现穿梭功能
    CASE2023
    [题] 筛质数 #质数(素数)
    API接口文档管理系统平台搭建(更新,附系统源码及教程)
    设置区块链节点输出等级为警告级,并把日志存储阈值位100MB并验证;
    基于Springboot的影城管理系统(有报告)。Javaee项目,springboot项目。
    面试(持续更新)
    浅析Spring事务实现原理
  • 原文地址:https://blog.csdn.net/hys__handsome/article/details/126151115