TreeMap中的floorKey()和ceilingKey()
1. 介绍
我们先看一看TreeMap类,实现了众多接口,它的这两个方法来自NavigableMap类:
public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable {...}
先看一看NavigableMap类中的floorKey()和ceilingKey()的API:
| 类型 | 方法 | 描述 |
|---|---|---|
| K | ceilingKey(K key) | 返回大于或等于给定键的最小键,如果没有这样的键,则null |
| K | floorKey(K key) | 返回小于或等于给定键的最大键,如果没有这样的键,则null |
而TreeMap中的这两个方法描述也是一样的,具体看一下源码,floorKey:
//floorKey(K key)
public K floorKey(K key) {
return keyOrNull(getFloorEntry(key));
}
//getFloorEntry(K key)
final Entry<K,V> getFloorEntry(K key) {
Entry<K,V> p = root;
while (p != null) {
int cmp = compare(key, p.key);
if (cmp > 0) {
if (p.right != null)
p = p.right;
else
return p;
} else if (cmp < 0) {
if (p.left != null) {
p = p.left;
} else {
Entry<K,V> parent = p.parent;
Entry<K,V> ch = p;
while (parent != null && ch == parent.left) {//获取到键中符合规定的最大键
ch = parent;
parent = parent.parent;
}
return parent;
}
} else
return p;
}
return null;
}
ceilingKey:
public K ceilingKey(K key) {
return keyOrNull(getCeilingEntry(key));
}
final Entry<K,V> getCeilingEntry(K key) {
Entry<K,V> p = root;
while (p != null) {
int cmp = compare(key, p.key);
if (cmp < 0) {
if (p.left != null)
p = p.left;
else
return p;
} else if (cmp > 0) {
if (p.right != null) {
p = p.right;
} else {
Entry<K,V> parent = p.parent;
Entry<K,V> ch = p;
while (parent != null && ch == parent.right) {//获取到键中符合规定的最小键
ch = parent;
parent = parent.parent;
}
return parent;
}
} else
return p;
}
return null;
}
示例:
public class Main {
public static void main(String[] args) {
Main m = new Main();
TreeMap<Integer,String> map = new TreeMap<>();
for (int i = 0; i < 10; i++)
map.put(2*i,"value"+i);
/**map:
* key: 0 1 2 3 4 5 6 7 8 9
* value:...
*/
map.floorKey(3);// 2
map.ceilingKey(3);// 4
}
}
在很多的需求中都能够使用到这一个方法。具体的需要注意的点就是这两个方法来之NavigableMap,在声明的时候最好使用TreeMap map = new TreeMap(),使用Map map = new TreeMap()是无法调用这两个方法的(这里涉及到向下转型的问题)。且TreeMap不保留存储顺序(内部以key升序)、key唯一等性质。
2. 实战使用
感兴趣的小伙伴可以看一看,挺有意思的…
https://ac.nowcoder.com/acm/contest/12949/E
import java.util.*;
public class Main {
private static TreeMap<Integer,Integer> map = new TreeMap<>();
private static int min = Integer.MAX_VALUE;
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int s = sc.nextInt();
int t = sc.nextInt();
int count = 1,step = 1,index = 1;
map.put(index,count);
while(index > -20000 && index < 20000){//准备数据
step *= -2;
index += step;
count++;
map.put(index,count);
}
jump(s,t,0);
System.out.print(min);
}
public static void jump(int s,int t,int count){//这一个count步数上一个count
if(s == t){
min = Math.min(min,count);
return;
}
if(count > min) return;//越过就结束,继续增加没有意义
if(count != 0) count++;
Integer floor = map.floorKey(t - s);
Integer ceil = map.ceilingKey(t - s);
jump(s + floor,t,count + map.get(floor));
if(ceil != null) jump(s + ceil,t,count + map.get(ceil));
}
}
本文介绍了Java TreeMap中的floorKey()和ceilingKey()方法,这两个方法源自NavigableMap接口。文章通过源码分析和实例演示,阐述了它们在实际应用中的使用场景,强调在声明时应使用NavigableMap,因为直接使用TreeMap可能无法调用这两个方法,同时提醒注意TreeMap的特性:key升序、key唯一。
907

被折叠的 条评论
为什么被折叠?



