我尝试使用递归来反转链表,但是我得到了奇怪的结果,以下是我的代码:
import java.util.LinkedList;
import java.util.List;
/**
* Created by liqiushi on 2/6/14.
*/
public class ReverseLinkedList {
public static void main(String[] args) {
List<Integer> list = new LinkedList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
reverse(list, 0);
for (int i : list) {
System.out.println(i);
}
}
private static void reverse(List<Integer> list, int index) {
if (list == null)
return;
if (index == 5) {
return;
}
int currentVal = list.get(0);
list = list.subList(1, list.size());
index += 1;
reverse(list, index);
list.add(currentVal);
}
}
执行的结果是:1 2 3 4 5 5 4 3 2 1,我哪里出错了?
P.S。我试图分析这个算法的时间复杂度,我认为它应该是O(n)因为它只是递归4次,就像一棵树,其中每个节点只有一个左或右孩子,如果我错了就纠正我。
答案 0 :(得分:2)
基本上,如果您想替换元素(而不是添加),则不应使用List#add
。
您可以执行以下操作:
private static void reverse(final List<Integer> list, final int index) {
if (index >= list.size()) {
return;
}
final int currentVal = list.get(index);
reverse(list, index + 1);
list.set(list.size() - 1 - index, currentVal);
}
虽然效率不高LinkedList
,但它会起作用。 :)
另一方面,如果您真的希望您的方法按add
- 元素运行到新的List
,那么它必须返回 { {1}}因此,其签名应为:
List
基本上,在这种情况下,你会:
private static List<Integer> reverse(final List<Integer> list, final int index)
的其余部分,最后List
末尾的当前元素。
例如:
List
(如果您这样做,请不要忘记在List
方法中迭代private static List<Integer> reverse(final List<Integer> list, final int index) {
if (index >= list.size()) {
return new LinkedList<>();
}
final List<Integer> res = reverse(list, index + 1);
res.add(list.get(index));
return res;
}
而不是直接reverse(list, 0)
最后一点,正如@Sundeep指出的那样,在这种情况下,使用一个简单的循环会更有效 - 但我们相信你真的想要玩递归......:)
答案 1 :(得分:0)
您要添加到已包含5个元素的列表中。如果您不想要原始元素,则应添加到新列表中。
答案 2 :(得分:0)
似乎对基本要求存在误解。
考虑一下:你想要删除列表中除最后一个元素之外的所有元素。改变列表(或子列表)是一个坏主意,因为导致的状态不是由自然递归定义的。
那就是说,让我们扔掉一些东西:
将传入的List
视为final
- 也就是说您无法重新分配或安全地修改它。
在你递归时耗尽清单。每个切片应比其上方的切片少一个。返回仅包含该切片的List
。
也不关心列表的大小。递归应该能够像调用堆栈允许的那样工作。
那说......考虑一下:
private static <Type> List<Type> listToReverse(int index, final List<Type> list) {
final List<Type> reversedList = new ArrayList<>();
if(index == list.size()) {
return reversedList;
} else {
reversedList.addAll(listToReverse(index++, list.subList(index, list.size())));
reversedList.add(list.get(index - 1));
}
return reversedList;
}
我故意将这个通用化,并将公开调用作为练习留给读者。
请记住基本情况 - 如果我正在阅读的当前“索引”位置等于列表本身的大小,我无所事事,所以我可以安全地返回空列表。然后,我逐渐开始将索引0中的元素添加到size - 1
。
E.g。如果我使用索引起始位置为0进行此递归调用,那么当我达到列表大小时,我将size - 1
中的元素添加到列表中。