树的搜索——leetcode

74. 搜索二维矩阵 - 力扣(LeetCode)

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int n = matrix.size(), m = matrix[0].size();
        int x = 0, y = m - 1;
        while(true)
        {
            if(x >= n || y < 0) return false;
            if(matrix[x][y] == target) return true;
            if(matrix[x][y] < target)
            {
                x ++;
            }
            else y --;
        }
        return true;
    }
};

173. 二叉搜索树迭代器 - 力扣(LeetCode)

class BSTIterator {
private:
    TreeNode* cur;
    stack<TreeNode*> stk;
public:
    BSTIterator(TreeNode* root): cur(root) {}
    
    int next() {
        while(cur != nullptr)
        {
            stk.push(cur);
            cur = cur->left;
        }
        cur = stk.top();
        stk.pop();
        int ret = cur->val;
        cur = cur->right;
        return ret;
    }
    
    bool hasNext() {
        return cur || !stk.empty();
    }
};

331. 验证二叉树的前序序列化 - 力扣(LeetCode)

671. 二叉树中第二小的节点 - 力扣(LeetCode)

class Solution {
public:
    int ans = -1;
    int findSecondMinimumValue(TreeNode* root) {
        dfs(root, root->val);
        return ans;
    }
    void dfs(TreeNode* root, int val)
    {
        if(root == nullptr) return;
        if(root->val != val)
        {
            if(ans == -1) ans = root->val;
            else ans = min(ans, root->val);
            return;
        }
        dfs(root->left, val);
        dfs(root->right, val);
    }
};

778. 水位上升的泳池中游泳 - 力扣(LeetCode)

优先队列

class Solution {
public:
    typedef pair<int,int> PII;
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int swimInWater(vector<vector<int>>& grid) {
       //深度优先搜索
        int n = grid.size(), m = grid[0].size();// x * m + y
        priority_queue <PII, vector<PII>, greater<PII> > q;
        vector<int> st(m * n);
        q.push({grid[0][0], 0});
        st[0] = true;//入队和出队都只有一次,所有保证入队一次即可
        int ans;
        int cnt = 0;
        while(!q.empty())
        {
            cnt ++;
            auto t = q.top();
            q.pop();
            int dep = t.first, u = t.second;
            if(u == m * n - 1)
            {
                ans = dep;
                break;
            }
            for(int i = 0; i < 4; i ++ )
            {
                int nx = dx[i] + u / m;
                int ny = dy[i] + u % m;
                if(nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
                if(st[nx * m + ny]) continue;//只会入队一次
                q.push({max(dep, grid[nx][ny]), nx * m + ny});
                st[nx * m + ny] = true;
            }
        }
        return ans;
    }
};

并查集

class Solution {
public:
    int f[2510];
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int find(int x)
    {
        if(f[x] == x) return x;
        return f[x] = find(f[x]);
    }
    int swimInWater(vector<vector<int>>& grid) {
        //从最小的开始,每次将这个点和周围比他小的点连接起来,直到起点和终点连接起来了
        vector<pair<int, int>> nums;
        int n = grid.size();
        for(int i = 0; i < n * n; i ++ ) f[i] = i;
        for(int i = 0; i < n; i ++ )
        for(int j = 0; j < n; j ++ )
        {
            nums.push_back({grid[i][j], i * n + j});
        }
        sort(nums.begin(), nums.end());//从小到大
        int ans;
        for(int i = 0; i < nums.size(); i ++ )
        {
            int dep = nums[i].first, u = nums[i].second;
            int a = find(u);
            for(int j = 0; j < 4; j ++ )
            {
                int nx = dx[j] + u / n;
                int ny = dy[j] + u % n;
                if(nx < 0 || ny < 0 || nx >= n || ny >= n) continue;
                if(dep > grid[nx][ny])
                {
                    int b = find(nx * n + ny);
                    f[b] = a; 
                }
            }
            if(find(0) == find(n * n - 1))
            {
                ans = dep;
                break;
            }
        }
        return ans;
    }
};

897. 递增顺序搜索树 - 力扣(LeetCode)

class Solution {
public:
    TreeNode* last;
    TreeNode* increasingBST(TreeNode* root) {
        //拉成链
        dfs(root);
        return last;
    }
    void dfs(TreeNode* root)
    {
        if(root == nullptr) return;
        TreeNode* l = root->left;
        dfs(root->right);
        root->right = last;
        root->left = nullptr;//每个节点都要有
        last = root;
        dfs(l);
    }
};

2

230. 二叉搜索树中第K小的元素 - 力扣(LeetCode)

class Solution {
public:
    int ans = -1;
    int cnt = 0;
    int kthSmallest(TreeNode* root, int k) {
        //中序遍历
        dfs(root, k);
        return ans;
    }
    void dfs(TreeNode* root, int k)
    {
        if(ans != -1) return ;//找到答案。
        if(root == nullptr) return ;
        dfs(root->left, k);
        cnt += 1;
        if(cnt == k) ans = root->val;//这说正好是根为第k小
        dfs(root->right, k);
    }
};

538. 把二叉搜索树转换为累加树 - 力扣(LeetCode)

逆中序遍历

class Solution {
public:
    int last = 0;
    TreeNode* bstToGst(TreeNode* root) {
        dfs(root);
        return root;
    }
    void dfs(TreeNode* root)
    {
        if(root == nullptr) return;
        
        dfs(root->right);
        root->val += last;
        last = root->val;
        dfs(root->left);
    }
};

450. 删除二叉搜索树中的节点 - 力扣(LeetCode)

class Solution {
public:
    //简单思路,遍历成链
    TreeNode* last = nullptr;
    TreeNode* deleteNode(TreeNode* root, int key) {
        dfs(root, key);
        return last;
    }
    void dfs(TreeNode* root, int key)
    {
        if(root == nullptr) return;
        TreeNode* r = root->right;//涉及last的一定要记录下当前的左右节点
        TreeNode* l = root->left;
        dfs(l, key);
        if(root->val != key)
        {
            root->left = last;
            root->right = nullptr;
            last = root;
        }
        dfs(r, key);
    }
};

98. 验证二叉搜索树 - 力扣(LeetCode)

class Solution {
public:
    bool flag = true;
    int last;
    int num = 1;
    bool isValidBST(TreeNode* root) {
        dfs(root);
        return flag;
    }
    void dfs(TreeNode* root)
    {
        if(root == nullptr || flag == false) return;
        dfs(root->left);
        if(num != 1)
        {
            if(root->val <= last) flag = false;
        }
        else num ++;
        last = root->val;
        dfs(root->right);
    }
};

701. 二叉搜索树中的插入操作 - 力扣(LeetCode)

递归搜索空节点

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root == nullptr) return new TreeNode(val);
        if(root->val > val) 
            root->left = insertIntoBST(root->left, val);
        if(root->val < val)
            root->right = insertIntoBST(root->right, val);
        return root;
    }
};

96. 不同的二叉搜索树 - 力扣(LeetCode)

class Solution {
public:
    int dp[100];
    int numTrees(int n) {
        dp[0] = 1;
        for(int i = 1; i <= n; i ++ )//总点数
        {
            for(int j = 1; j <= i; j ++ )//根节点的位置
            {
                dp[i] += dp[j - 1] * dp[i - j];
            }
        }
        return dp[n];
    }
};

95. 不同的二叉搜索树 II - 力扣(LeetCode)

寻找1-n的所有左右儿子节点

class Solution {
public:
    vector<TreeNode*> generateTrees(int n) {
        if(n == 0) return {};
        return build(1, n);
    }
    vector<TreeNode*> build(int l, int r)
    {
        vector<TreeNode*> res;
        if(l > r)
        {
            res.push_back(nullptr);
            return res;
        }
        for(int i = l; i <= r; i ++ )
        {
            vector<TreeNode*> ltree = build(l, i - 1);
            vector<TreeNode*> rtree = build(i + 1, r);
            for(auto left: ltree)
            for(auto right: rtree)
            {
                TreeNode* root = new TreeNode(i);
                root->left = left;
                root->right = right;
                res.push_back(root);
            }
        }
        return res;
    }

};

1373. 二叉搜索子树的最大键值和 题解 - 力扣(LeetCode)

class Solution {
private:
    // 记录全局的最大键值和
    int maxRes = 0;
    // 返回值
    // 0: 1是搜索树,0不是搜索树
    // 1: 最小值
    // 2: 最大值
    // 3: 总和: 对于非搜索树,直接返回0
    vector<int> dfs(TreeNode* curr)
    {
        if (curr == nullptr)
        {
            return {1, INT_MAX, INT_MIN, 0};
        }
        auto l = dfs(curr->left);
        auto r = dfs(curr->right);

        vector<int> res(4, 0);
        // 只有满足二叉搜索树,才返回结果
        // cout << l[0] << " " << r[0] << " " << l[2] << " " << r[1] << " : " << curr->val << endl;
        if (l[0] == 1 && r[0] == 1 && l[2] < curr->val && r[1] > curr->val)
        {
            res[0] = 1;
            res[1] = min(l[1], curr->val);
            res[2] = max(r[2], curr->val);
            res[3] = l[3] + r[3] + curr->val;
            maxRes = max(maxRes, res[3]);
        }

        return res;
    }
public:
    int maxSumBST(TreeNode* root) {
        dfs(root);

        return maxRes;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值