1. 题目描述
2. 解题思路
一个最简单的想法就是把链表遍历后存入到栈当中,然后再弹栈构建新的链表,想法很简单,可是时间效率不高。那有方法可以遍历一次链表就可以完成反转操作吗?我们可以对链表中的节点进行逐位反转,先存储当前节点的后继节点,然后把当前节点的前驱节点指认为当前节点的后继节点,如此操作只需要遍历一次即可完成反转操作。
3. 解题思路
3.1 利用栈
public ListNode reverseList(ListNode head) {
if (head != null) {
Deque<Integer> stack = new LinkedList<>();
while (head != null) {
stack.push(head.val);
head = head.next;
}
System.out.println(stack);
ListNode listNode = new ListNode();
ListNode ans = listNode;
listNode.val = stack.pop();
while (!stack.isEmpty()) {
listNode.next = new ListNode();
listNode = listNode.next;
listNode.val = stack.pop();
}
return ans;
}
return null;
}
3.2 逐位逆转
public ListNode reverseList(ListNode head) {
if (head != null) {
ListNode pre = null;
while (head!=null){
ListNode next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
return null;
}
3.3 对比
虽然两种算法的时间复杂度都是O(n),但构建辅助栈再弹出实际上是等于两次遍历操作,因此也消耗了更多的时间;空间复杂度而言,链表有多长辅助栈就需要多大的空间,因此其空间复杂度是O(n),而逐位反转只需要两个辅助变量存储当前节点的前驱节点与后继节点,因此其空间复杂度是O(1)。