假设我们有一组N个范围,(A1,B1)(A2,B2)(A3,B3)...(An,Bn),其中Ai表示起点,Bi表示a的终点。范围。 (Ai,Bi是正整数)
如果给定的整数(例如X)存在于N个范围中的至少一个范围内,我们如何使用二进制搜索进行检查?
我的方法:
首先按x坐标排序,然后按y坐标排序。
找到大于或等于X的最小x坐标。
检查是否满足该范围。
如果是,我们有解决方案。
现在,如果该范围不包含X,我的下一步应该是什么?
或者,解决方案应该完全不同吗?
答案 0 :(得分:1)
首先,如果范围没有排序,你最好逐个检查而不是进行任何花哨的二进制搜索,因为检查每个范围最多是O(n),而排序然后是二进制搜索将至少为O(n log n)。
无论如何,在这种情况下,我会将具有相同x坐标的所有范围视为单个节点,因此当您进行二进制搜索时,您获得的中间节点实际上将是具有的范围组相同的x坐标。然后,您将检查该节点中最后一个范围的y坐标。如果数字不在这两个之间,则该数字不包含在节点的任何范围内,因此您应该向左或向右,具体取决于数字是高于还是低于x或y坐标。
这是Python中一个完整的工作示例:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import itertools
MAX = 50
NUM_RANGES = 30
THE_NUMBER = random.randint(0, MAX)
ranges = []
# Generate random ranges
for e in range(NUM_RANGES):
x = random.randint(0, MAX - 1)
y = random.randint(x + 1, MAX)
ranges.append((x,y))
# Group the ranges by starting coordinate
grouped_ranges = {x: [e for e in ranges if e[0] == x] for x in (e[0] for e in ranges)}
## Binary search
gkeys = grouped_ranges.keys()
gkeys_range = [0, len(gkeys)]
get_mid_key = lambda: (gkeys_range[1] + gkeys_range[0])/2
get_mid = lambda: grouped_ranges[gkeys[get_mid_key()]]
print "THE NUMBER:", THE_NUMBER
print "THE RANGES:", grouped_ranges
while 1:
# Get middle element
mid = get_mid()
print gkeys_range
old_range = gkeys_range[:]
if THE_NUMBER < mid[0][0]:
gkeys_range[1] = get_mid_key()
elif THE_NUMBER > mid[-1][1]:
gkeys_range[0] = get_mid_key()
else:
print "In this range:", mid
break
if gkeys_range == old_range:
print "Not in any range"
break
答案 1 :(得分:1)
我从您的问题描述中得到的是pairs
(a1,b1) , (a2,b2)
。 ax
是范围的开头且bx
结束的位置。现在,您将获得一个数字n
,并且您想要搜索该数字是否在任何范围内
首先排序,然后合并重叠范围,然后应用二进制搜索:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
vector < pair <int , int> > b;
b.push_back(make_pair(5,10));
b.push_back(make_pair(75,100));
b.push_back(make_pair(33,67));
b.push_back(make_pair(9,21));
b.push_back(make_pair(28,67));
int m = b.size();
sort(b.begin(), b.end());
int j = 0;
for (int i = 1; i < m; i++) {
if (b[i].first <= b[j].second) {
if (b[i].second > b[j].second) {
b[j].second = b[i].second;
}
}
else {
j++;
b[j] = b[i];
}
}
m = j + 1;
for(int i = 0; i< m;i ++) {
cout << b[i].first << " " << b[i].second << endl;
}
// Apply binary search now
return 0;
}
我希望这能解决你的问题。我已经把二元搜索部分留给你了。