考虑一些名为long
的{{1}}和一个已排序的X
。在List<Long>
中找到(i)小于List<Long>
和(ii)的索引或值的最有效算法是什么?在数字线上最接近X
(假设条件(i)已被饱和)?
例如,这可能是一个问题设置:
X
我希望算法返回long X = 500;
List<Long> foo = new Arraylist<Long>();
foo.add(450L);
foo.add(451L);
foo.add(499L);
foo.add(501L);
foo.add(550L);
Collections.sort(foo); // It's always sorted.
或返回与499
相关联的索引(在本例中为499
)。
答案 0 :(得分:16)
鉴于列表中的值是唯一的,我建议您使用Set
,更具体地说是TreeSet
,因为您无论如何都要对列表进行排序。您可以使用完全符合要求的NavigableSet#floor(E)
方法。
返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回
null
。
所以,代码看起来像:
long X = 500;
NavigableSet<Long> foo = new TreeSet<Long>();
foo.add(450L);
foo.add(451L);
foo.add(499L);
foo.add(501L);
foo.add(550L);
System.out.println(foo.floor(X)); // 499
该方法也适用于用户定义的对象。只需在实例化时将Comparator<YourClass>
传递给TreeSet
构造函数。
答案 1 :(得分:6)
/ *在列表中找到最近的号码 * @param整数列表 * @param num到最接近的数字 * @return最近的号码 * * /
public static int findClosestNumber(List list, int num) {
if (list.size() > 0) { // Check list does not empty
int smaller =
(Integer)Collections.min(list); // get min number from the list
int larger =
(Integer)Collections.max(list); // get max number from the list
for (int i = 0; i < list.size(); i++) { //Traverse list
if (num == (Integer)list.get(i)) //if find the passed number in the list
return num; //than return num
if (num > (Integer)list.get(i) && smaller < (Integer)list.get(i)) // find nearest smaller
smaller = (Integer)list.get(i);
if (num < (Integer)list.get(i) && larger > (Integer)list.get(i)) // find nearest larger
larger = (Integer)list.get(i);
}
return (num - smaller < larger - num ? smaller : larger); // return closest number
}
return 0;
}
}
答案 2 :(得分:5)
您可以使用java的Collections.binarySearch
,因为您的列表已经过排序。
在the spec中,二进制搜索返回:
搜索键的索引(如果它包含在列表中); 否则,( - (插入点) - 1)。插入点定义为 键将插入列表的位置:索引 第一个元素大于键,或list.size()如果全部 列表中的元素小于指定的键。请注意这一点 当且仅当密钥时,保证返回值>&gt; = 0 找到了。
首先,如果你进行二元搜索并且元素在列表中,你将获得一个正值(元素的索引),并且可以返回它(或者如果你仍然想要一个你可以少的元素从那里向后走,直到找到一个。)
否则,如果搜索列表中没有的内容,则可以从返回值向后返回所需的索引。如果在示例列表中搜索500,则算法将返回(-3 - 1)= -4。因此,您可以添加1以返回到插入点(-3),然后乘以-1并减去1以获得索引BEFORE第一个元素GREATER而不是您搜索的元素,这将是一个索引如果列表中的所有元素都大于您搜索的元素,则符合您的2个条件或-1。
在树集上使用二进制搜索的优点是它可能会减少开销。