今日份每日一题

本文探讨了在二叉搜索树(BST)中,如何使用数组代替传统树结构来避免内存问题,并介绍了利用LCA(最近公共祖先)算法计算两个节点之间的距离。通过两种建树策略和详细代码实现,展示了在给定列表中寻找特定节点距离的解决方案。
摘要由CSDN通过智能技术生成

@今日份每日一题:BST节点距离
在这里插入图片描述

解题思路

该题的思路总的来说可以分为 建树+LCA
但是值得注意的是,建树有两种方案

  1. 直接按照节点建树
  2. 可以用数组代替树,可参考堆结构。
    但是目前存在的问题是,题设条件无法知道数据状况,因为数据的输入状况可能导致树转换为链表的形式,这就可能造成数据的大小需要 2 n 2^n 2n,可能会爆内存。更加好的按照数组建树的方法,我还没有想出来,有感兴趣的小伙伴可以想一想。写出来请踢我一下,谢谢!
1. LCA思路

各位请参考 lec236 LCA;
稍微有点不同的地方都在代码里边啦!

2. 代码
#include<vector>
#include<iostream>
using namespace std;

class Solution {
    class TreeNode {
    public:
        int val;
        TreeNode* left;
        TreeNode* right;

        TreeNode(int v = 0, TreeNode* l = nullptr, TreeNode* r = nullptr) :val(v), left(l), right(r) {}
        TreeNode(TreeNode &&root) noexcept{
            val = root.val;
            left = root.left;
            right = root.right;

        }

        ~TreeNode() {
            if (left) {
                delete left;
            }
            if (right) {
                delete right;
            }
        }
    };

    class Tree : public TreeNode
    {
        TreeNode* root;
        typedef pair<int, int> pii;
        /*
            key : -1,0,1
                -1: 未找到
                 0: 找到了一个
                 1: 两个都找到了
            value: 表示找到的节点距离当前节点的长度
        */

        pii LCA(TreeNode* cur, int v1, int v2) {
            if (nullptr == cur) {
                return make_pair(-1, -1);
            }
            bool flag = false;
            if (cur->val == v1 || cur->val == v2) {
                flag = true;
            }
            pii left = LCA(cur->left, v1, v2);
            pii right = LCA(cur->right, v1, v2);

            if (flag) {
                // 1. 当前节点就是需要寻找的某一个节点
                // 1.1 如果左右找到了另外一个节点,距离就是左右距离当前节点的距离+1
                if (left.first == 0) {
                    return make_pair(1, left.second + 1);
                }
                if (right.first == 0) {
                    return make_pair(1, right.second + 1);
                }

                // 1.2 如果左右都没有,那就相当于在这个节点找到了其中的某一个节点
                return make_pair(0, 0);
            }
            else {
                // 2. 当前节点不是需要寻找的节点
                // 2.1 如果左右节点已经可以返回, 直接返回就好
                if (left.first == 1) {
                    return make_pair(1, left.second);
                }
                if (right.first == 1) {
                    return make_pair(1, right.second);
                }

                // 2.2 如果左右节点都找到了
                if (left.first == 0 && right.first == 0) {
                    return make_pair(1, right.second + left.second + 2);
                }

                // 如果左右有一个找到了
                if (left.first == 0) {
                    return make_pair(0, left.second + 1);
                }
                if (right.first == 0) {
                    return make_pair(0, right.second + 1);
                }
            }

            // 3. 啥玩意没有,直接返回没找到
            return make_pair(-1, -1);
        }
    public:
        Tree(int val):root(std::move(new TreeNode(val))){
        
        }
        ~Tree() {
            delete root;
        }

        void insert(int val) {
            TreeNode* cur = root;
            while (1) {
                if (cur->val > val) {
                    if (nullptr == cur->left) {
                        cur->left = new TreeNode(val);
                        break;
                    }
                    cur = cur->left;
                }
                else if (cur->val < val) {
                    if (nullptr == cur->right) {
                        cur->right = new TreeNode(val);
                        break;
                    }
                    cur = cur->right;
                }
                else {
                    break;
                }
            }
        }

        int LCA(int v1, int v2) {
            pii ans = LCA(this->root, v1, v2);
            return ans.first != 1 ? -1 : ans.second;
        }
    };
public:
    /**
     * @param numbers: the given list
     * @param node1: the given node1
     * @param node2: the given node2
     * @return: the distance between two nodes
     */
    int bstDistance(vector<int>& numbers, int node1, int node2) {
        // Write your code here
        // 暴力解法:建树+LCA
        /*
            1.因为BST插入节点总是插入到空位置,所以就简单建树就好了
            - 但是注意,建树后的数组长度可不是原来的长度,按照最坏的打算,应该是2^n (暂时拿树来模拟)
            2.LCA算法
        */
        int n = numbers.size();
        if (n < 2) {
            return -1;
        }

        Tree t(numbers[0]);
        for (int i = 1; i < n; ++i) {
            t.insert(numbers[i]);
        }

        return t.LCA(node1, node2);
    }
};

int main()
{
    vector<int> nums = { 10,18,12,16,19,13,20,3,1,7,14 };
    Solution s;
    s.bstDistance(nums, 18, 7);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值