LintCode 11. Search Range in Binary Search Tree

  1. Search Range in Binary Search Tree
    中文English
    Given a binary search tree and a range [k1, k2], return node values within a given range in ascending order.

Example
Example 1:

Input:{5},6,10
Output:[]
5
it will be serialized {5}
No number between 6 and 10
Example 2:

Input:{20,8,22,4,12},10,22
Output:[12,20,22]
Explanation:
20
/
8 22
/
4 12
it will be serialized {20,8,22,4,12}
[12,20,22] between 10 and 22

解法1:
先把inOrder Traversal的结果求出来,再比较。
注意:

  1. lower_bound()和upper_bound()返回结果都是iterator,必须减去inOrderList.begin();
  2. lower_bound()和upper_bound()都是基于排序数组,因为要用二分查找。
  3. lower_bound(l,r,m)在l和r中的前闭后开区间进行二分查找,返回大于或等于m的第一个元素位置 (或者说返回m的第一个可插入位置)。如果所有元素都小于m, 则返回r的位置(注意r是最后一个元素的后一个位置,因为是前闭后开区间)。

Example: vector nums = {4,10,11,30,69,70,96,100}。设要插入数字3,9,111, pos为要插入的位置的下标

pos = lower_bound( nums.begin(), nums.end(), 3) - nums.begin(),pos = 0
pos = lower_bound( nums.begin(), nums.end(), 9) - nums.begin(), pos = 1
pos = lower_bound( nums.begin(), nums.end(), 111) - nums.begin(), pos = 8 (最后一个元素的下一个元素)。

返回查找元素的第一个可插入位置,也就是“元素值>=查找值”的第一个元素的位置
4) upper_bound(l,r,m)在l和r中的前闭后开区间进行二分查找,返回最后一个m在数组中的下标+1。
特殊情况:
a.如果m在区间中没有出现过,那么返回第一个比m大的数的下标。
b.如果m比所有区间内的数都大,那么返回r。这个时候会越界,小心。
c.如果区间内有多个相同的m,返回最后一个m的下标+1。
5) lower_bound的意义是对于给定的已经排好序的a,key最早能插入到那个位置
upper_bound的意义是对于给定的已经排好序的a,key最晚能插入到那个位置

举例:
int a[]={0,1,2,2,3};
lower_bound(a,a+5,2)-a); //=2
upper_bound(a,a+5,2)-a); //=4

结果:2 4
0 1 | 2 2 3 所以2最早插入到2号位置
0 1 2 2 | 3 所以2最晚插入到4号位置0 1 | 2 2 3 所以2最早插入到4号位置
6) lower_bound()和upper_bound()还可以加入cmp函数。

代码如下:

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param root: param root: The root of the binary search tree
     * @param k1: An integer
     * @param k2: An integer
     * @return: return: Return all keys that k1<=key<=k2 in ascending order
     */
    vector<int> searchRange(TreeNode * root, int k1, int k2) {
        if (!root || k1 > k2) return vector<int>();
        inOrderTraversal(root);
        int n = inOrderList.size();
  
        vector<int> result;
        
        int low = lower_bound(inOrderList.begin(), inOrderList.end(), k1) - inOrderList.begin();

        if (low >= n) return vector<int>();
        
        int up = upper_bound(inOrderList.begin(), inOrderList.end(), k2) - inOrderList.begin();
        if (up > n) return vector<int>();
        
        for (int i = low; i < up; ++i) {
            result.push_back(inOrderList[i]);
        }
        return result;
    }

private:
    void inOrderTraversal(TreeNode * root) {
        if (!root) return;
        inOrderTraversal(root->left);
        inOrderList.push_back(root->val);
        inOrderTraversal(root->right);
    }
    
    vector<int> inOrderList;
};

解法2:直接在inOrderTraversal里面判断。一步到位。
代码如下:

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param root: param root: The root of the binary search tree
     * @param k1: An integer
     * @param k2: An integer
     * @return: return: Return all keys that k1<=key<=k2 in ascending order
     */
    vector<int> searchRange(TreeNode * root, int k1, int k2) {
        if (!root || k1 > k2) return vector<int>();
        inOrderTraversal(root, k1, k2);
        return result;
    }

private:
    void inOrderTraversal(TreeNode * root, int k1, int k2) {
        if (!root) return;
        inOrderTraversal(root->left, k1, k2);
        if (root->val >= k1 && root->val <= k2) {
            result.push_back(root->val);
        }
        inOrderTraversal(root->right, k1, k2);
    }
    vector<int> result;

};

解法3:先找出最开始处于k1,k2中的那个root,然后in-order迭代,如果发现某个节点>k2,那么就退出。

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param root: param root: The root of the binary search tree
     * @param k1: An integer
     * @param k2: An integer
     * @return: return: Return all keys that k1<=key<=k2 in ascending order
     */
    vector<int> searchRange(TreeNode *root, int k1, int k2) {
        vector<int> res;
        stack<TreeNode *> stk;
        while (root) {
            if (root->val >= k1) break;
            if (root->val < k1) {
                root = root->right;
                if (root && root->val >= k1) {
                    break;
                }
            }
        }

        while (root || !stk.empty()) {
            while (root) {
                stk.push(root);
                root = root->left;
            }
            root = stk.top();
            stk.pop();
            if (root->val >= k1 && root->val <= k2) {
                res.push_back(root->val);
            } else if (root->val > k2) {
                break;
            }
            root = root->right;
        }
        return res;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值