[LeetCode] 98. Validate Binary Search Tree

博客围绕验证二叉树是否为有效二叉搜索树(BST)展开,介绍了BST的定义,并给出示例。解析部分指出可通过递归和中序遍历两种方法判断,递归要考虑INT最值情况,中序遍历可判断是否有序,还给出了相关参考链接。

Validate Binary Search Tree

Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than the node’s key.
Both the left and right subtrees must also be binary search trees.
Example:

Input:
2
/ \
1 3
Output: true

解析

判断二叉树是否为BST,递归判断左右子树是否为BST,并判断左子树最大值小于根节点的值,右子树最小值大于根节点的值。,可以使用递归和中序遍历两种方法来解决。

解法1:递归

递归判断左右子树和左右最大的值,但是需要考虑INT的最大最小值情况,所以使用LONG。

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        if(!root)
            return true;
        if(!root->left && !root->right)
            return true;
        if(root->left || root->right){
            long left_max = LONG_MIN;
            long right_min = LONG_MAX;
            TreeNode* p = root->left;
            while(p){
                left_max = max(left_max, long(p->val));
                p = p->right;
            }
            p = root->right;
            while(p){
                right_min = min(right_min, long(p->val));
                p = p->left;
            }
            return left_max < root->val && right_min > root->val && isValidBST(root->left) && isValidBST(root->right) ;
        }
        return false;
    }
};

还可以构建新的递归函数来解决。

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        return isValidBST(root, LONG_MIN, LONG_MAX);
    }

    bool isValidBST(TreeNode* root, long left_max, long right_min){
        if(!root)
            return true;
        if(left_max >= root->val || right_min <= root->val)
            return false;
        return isValidBST(root->left, left_max, root->val) && isValidBST(root->right, root->val, right_min);
    }
};

解法2:中序遍历

可以选择得到完整的中序遍历判断是否有序,也可以在得到中序遍历的过程中判断是否有序,对于中序遍历又有好几种方法,具体可以参考Binary Tree Inorder Traversal

参考

http://www.cnblogs.com/grandyang/p/4298435.html
https://blog.youkuaiyun.com/Peng_maple/article/details/82155101

<think> 我们正在处理用户关于在sklearn中使用Haversine距离时出现的“ValueError: Haversine distance only valid in 2 dimensions”错误的问题。 根据用户提供的引用,我们并没有直接关于Haversine距离错误的引用,但是我们可以根据错误信息和Haversine距离的要求来提供解决方案。 Haversine距离是用于计算球面上两点之间的大圆距离,通常用于地理坐标(经度和纬度)。这个距离度量要求输入数据必须是二维的,即每行数据包含经度和纬度两个值。 错误信息“Haversine distance only valid in 2 dimensions”表明输入数据的维度不是2。可能的原因包括: 1. 输入数据的每个样本的特征数量超过了2(比如包含了高度、时间等其他维度)。 2. 输入数据的维度不是2,可能是3维或更高,或者只有1维。 因此,解决方法如下: 1. 确保输入数据是二维的,且只有经度和纬度两列。如果数据包含其他列(如高度、ID等),则需要先进行特征选择,只保留经度和纬度列。 2. 检查数据的形状,可以使用`X.shape`查看,确保列数为2。 例如,在使用`sklearn.neighbors`中的`BallTree`或`KDTree`时,如果使用Haversine距离,需要传入的数据必须是两列(第一列是纬度,第二列是经度,注意顺序通常要求是弧度制,但也可以通过设置参数来使用度数)。 另外,注意Haversine距离函数要求输入数据是弧度制。如果数据是度数,需要先转换为弧度。可以使用`numpy.deg2rad`进行转换。 示例代码: 假设我们有一个数据集`X`,包含经度和纬度(以度为单位),并且还有其他列(如高度): ```python import numpy as np from sklearn.neighbors import BallTree # 假设X是一个numpy数组,其中前两列是纬度和经度(以度为单位) # 我们只取前两列 X_geo = X[:, :2] # 将度数转换为弧度 X_rad = np.deg2rad(X_geo) # 现在使用BallTree,度量选择haversine tree = BallTree(X_rad, metric='haversine') ``` 这样就应该可以避免上述错误。 另外,如果使用`DistanceMetric`类,同样要注意: ```python from sklearn.metrics import DistanceMetric dist = DistanceMetric.get_metric('haversine') # 然后使用弧度制的二维数据 ``` 所以,总结解决办法: - 确保数据只有两维(经度和纬度) - 将数据从度数转换为弧度(如果原始数据是度数) 如果用户的数据不是经纬度,或者包含了其他维度,那么需要先进行预处理,只保留经纬度并转换为弧度。 注意:在sklearn中,Haversine距离的实现要求数据是弧度制的二维数组。 因此,用户需要检查输入数据的维度和单位。 如果用户的问题还未解决,可能需要检查数据的具体情况。 根据上述分析,我们给用户提供解决方案。 </think>### 解决 `ValueError: Haversine distance only valid in 2 dimensions` 错误的方法 在 scikit-learn 中使用 Haversine 距离计算地理空间距离时,出现该错误的原因是 **输入数据的维度不符合要求**。Haversine 距离是专门用于计算球面上两点间距离的公式(如地球表面),要求输入数据必须是二维的(经度和纬度)。以下是完整的解决方案: #### 1. 检查数据维度(核心步骤) 确保输入矩阵是严格的二维数据(N×2 矩阵): ```python import numpy as np # 检查数据形状(必须是 N 行 × 2 列) print(your_data.shape) # 应显示 (n_samples, 2) # 错误示例:三维数据会报错 invalid_data = np.array([[1, 2, 3], [4, 5, 6]]) # 3列 → 报错 # 正确示例:二维经纬度数据 correct_data = np.array([ [40.7128, -74.0060], # 纽约 [51.5074, -0.1278] # 伦敦 ]) ``` #### 2. 转换数据格式(若使用度数) Haversine 默认要求**弧度制**输入,若数据是度数需转换: ```python from sklearn.neighbors import DistanceMetric # 将度数转换为弧度 data_radians = np.radians(correct_data) # 创建距离计算器 haversine = DistanceMetric.get_metric('haversine') # 计算距离矩阵(结果为球面距离,单位:公里) dist_matrix = haversine.pairwise(data_radians) * 6371 # 6371=地球半径(km) ``` #### 3. 在算法中的正确用法 以 `BallTree` 为例: ```python from sklearn.neighbors import BallTree # 正确:二维弧度制数据 tree = BallTree(data_radians, metric='haversine') # 查询示例 distances, indices = tree.query([[np.radians(35.6895), np.radians(139.6917)]], k=3) # 东京的邻近点 ``` #### 4. 常见错误场景及修复 | 错误场景 | 修复方法 | |--------------------------|--------------------------------------------------------------------------| | 数据包含海拔高度(3列) | 只保留前两列:`data = data[:, :2]` | | 数据为单维度(1列) | 检查数据源,确保包含经纬度两列 | | 未转换为弧度制 | 添加转换:`np.radians(data)` | | 使用 `pairwise_distances` | 显式指定维度:`pairwise_distances(data_radians, metric='haversine')` | #### 5. 完整工作流示例 ```python # 生成示例数据(经纬度度数) cities = np.array([ [35.6895, 139.6917], # 东京 [40.7128, -74.0060], # 纽约 [51.5074, -0.1278] # 伦敦 ]) # 1. 维度校验 assert cities.shape[1] == 2, "必须为二维数据!" # 2. 度数转弧度 cities_rad = np.radians(cities) # 3. 计算距离矩阵 dist_calculator = DistanceMetric.get_metric('haversine') dist_km = dist_calculator.pairwise(cities_rad) * 6371 print("城市间距离矩阵(公里):") print(dist_km) ``` **关键说明**: - Haversine 公式只能处理二维坐标,因为它是基于球面几何的[^1] - 若需处理三维空间距离(含海拔),应改用 `euclidean` 或 `manhattan` 距离[^2] - 计算结果单位是公里(乘以地球半径后),不乘半径时结果为弧度[^3]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值