【面试题】多区间二分查找

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Somnus_k/article/details/82492381

接上篇ip地址转整数。

题目1:设计一个数据结构,里面包含ip地址的范围以及该范围内ip地址对应的城市,ip地址均采用整数形式表示。

class IP2City{
	String city;//如果city有id,用id也可以
	Long start;
	Long end;
}

题目2:如果给你一个ip地址,快速判断它属于哪个城市,各个ip区间没有重叠的情况。

当时的做法是:对n个区间对象进行遍历,和目的ip地址进行比较,时间复杂度O(n),面试官要求速度更快,这样的话就只能采用二分查找了。

比如:[1,10],[11,15],[16,27],[28,67],[68,79][80,100],求18在哪个区间内。

思路是:取每个区间最小值进行二分查找,并对边界进行判断。

class IP2City{
	String city;//如果city有id,用id也可以
	Long start;
	Long end;
	public IP2City(String city, Long start, Long end) {
		this.city = city;
		this.start = start;
		this.end = end;
	}
	
}

public class Test {
	public static void main(String[] args) {
		List<IP2City> list = new ArrayList<>();
		IP2City city1 = new IP2City("beijing", 1l, 10l);
		IP2City city2 = new IP2City("shanghai", 11l, 15l);
		IP2City city3 = new IP2City("shenzhen", 16l, 27l);
		IP2City city4 = new IP2City("zhengzhou", 28l, 67l);
		IP2City city5 = new IP2City("hefei", 68l,79l);
		IP2City city6 = new IP2City("chengdu", 80l, 100l);
		list.add(city1);
		list.add(city2);
		list.add(city3);
		list.add(city4);
		list.add(city5);
		list.add(city6);
		
		System.out.println(findCityByIp(18l,list));
		System.out.println(findCityByIp(28l,list));
		System.out.println(findCityByIp(70l,list));
		System.out.println(findCityByIp(100l,list));
	}

	private static String findCityByIp(long ip,List<IP2City> list) {
		int low = 0;
		int hi = list.size()-1;
		if(ip<low||ip>list.get(list.size()-1).end)
			return null;
		if(ip>list.get(list.size()-1).start)
			return list.get(list.size()-1).city;
		while(low<hi){
			int mid = (low+hi)/2;
			if(list.get(mid).start>ip)
				{if(mid==hi)
						return list.get(mid).city;
				hi=mid;
				}
			else if(list.get(mid).start<ip)
				{
				if(mid==low)
					return list.get(mid).city;
				low=mid;
				}
			else
				return list.get(mid).city;
		}
		return list.get(low).city;
	}
}

结果:

猜你喜欢

转载自blog.csdn.net/Somnus_k/article/details/82492381
今日推荐