输入一个链表的头节点,从尾到头反过来打印每个节点的值。例如:1->2->3->4->5,打印输出成5->4->3->2->1。
public class TestMethod6 {
public static void main(String[] args) {
ListNode<Integer> node5 = new ListNode<Integer>(5);
ListNode<Integer> node4 = new ListNode<Integer>(4, node5);
ListNode<Integer> node3 = new ListNode<Integer>(3, node4);
ListNode<Integer> node2 = new ListNode<Integer>(2, node3);
ListNode<Integer> node1 = new ListNode<Integer>(1, node2);
//method1(node1);
//method2(node1);
method3(node1);
}
/**
* 递归方法实现
* 复杂度分析:时间O(n),空间O(n)
* 存在的问题:当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。
* 鲁棒性相对于栈方法实现较差
*
* @param node
*/
public static void method1(ListNode node) {
if (node != null) {
if (node.next != null) {
method2(node.next);
}
System.out.print(node + " ");
}
}
/**
* 栈方法实现
* 复杂度分析:时间O(n),空间O(n)
*
* @param node
*/
public static void method2(ListNode node) {
Stack<ListNode> stack = new Stack<ListNode>();
while (node != null) {
stack.push(node);
node = node.next;
}
StringBuilder str = new StringBuilder();
while (!stack.empty()) {
str.append(stack.pop() + " ");
}
System.out.println(str.toString());
}
/**
* 反转单链表,然后再打印
* 复杂度分析:时间O(n),空间O(1)
*
* @param node
*/
public static void method3(ListNode node) {
ListNode curr = node;
ListNode prev = null;
while (curr != null) {
ListNode tempNext = curr.next;
curr.next = prev;
prev = curr;
curr = tempNext;
}
StringBuilder str = new StringBuilder();
while (prev != null) {
str.append(prev + " ");
prev = prev.next;
}
System.out.println(str.toString());
}
public static class ListNode<E> {
public E value;
public ListNode next;
public ListNode() {
this(null);
}
public ListNode(E value) {
this(value, null);
}
public ListNode(E value, ListNode next) {
this.value = value;
this.next = next;
}
@NonNull
@Override
public String toString() {
return value.toString();
}
}
}
解题思路
复杂度分析
- 方法一的时间复杂度:O(n),空间复杂度:O(n)
- 方法二的时间复杂度:O(n),空间复杂度:O(n)
- 方法三的时间复杂度:O(n),空间复杂度:O(1)