我尝试编写的这个方法在列表中找到整数的最大值,对于赋值我必须使用递归。我想我理解递归的概念,但是用列表或数组做这件事是我不明白的。是否总是需要将List或数组分成两半?无论如何,这段代码会编译,但我在下面评论的一行中得到了一个IndexOutOfBounds错误。它看起来与我应该做的非常接近吗?
public static final int findMaxRecursively(List<Integer> numbers) {
int max = 0;
if(numbers.size() == 1)
return numbers.size();
List<Integer> bottomHalf = new ArrayList<Integer>(numbers.size()/2);
for (int i= 0; i<numbers.size()/2;i++){
if (bottomHalf.get(i) > max) // here's where the IndexOutOfBounds error occurs
max = bottomHalf.get(i);
}
findMaxRecursively(bottomHalf);
List<Integer> topHalf = new ArrayList<Integer>(numbers.size()/2);
for(int i = numbers.size()/2; i< numbers.size(); i++){
if (topHalf.get(i) > max)
max = topHalf.get(i);
}
findMaxRecursively(topHalf);
return max;
}
答案 0 :(得分:2)
你的递归调用毫无意义,因为你向它们传递空列表,即使它们返回了正确的值,你也没有对返回的值做任何事情。
为了递归地找到max元素,您应该拆分列表。最有效的分割是两个相等的部分。
按new ArrayList<Integer>(numbers.size()/2)
创建列表并不会将原始列表的一半元素复制到此列表中。它只是创建一个空列表,其初始容量是原始列表大小的一半。
您可以使用List<E> subList(int fromIndex, int toIndex);
来查看列表的一部分。
当numbers.size() == 1
时,您应该返回numbers.get(0)
而不是numbers.size()
。
最后,让for循环失败了递归解决方案的目的。在递归解决方案中,您只需进行2次递归调用以获取下半部分和上半部分的最大值,然后比较两个返回值并返回较大值。
public static final int findMaxRecursively(List<Integer> numbers)
{
if(numbers.size() == 1)
return numbers.get(0);
List<Integer> bottomHalf = numbers.subList(0,numbers.size()/2);
int bottom = findMaxRecursively(bottomHalf);
List<Integer> topHalf = numbers.subList(numbers.size()/2,numbers.size());
int top = findMaxRecursively(topHalf);
return top>bottom?top:bottom;
}