算法思想一:双指针迭代
解题思路:
(1)定义两个指针: pre 和 cur ;pre 在前 cur 在后。
(2)每次让 pre 的 next 指向 cur ,实现一次局部反转
(3)局部反转完成之后, pre 和 cur 同时往前移动一个位置
(4)循环上述过程,直至 pre 到达链表尾部
(2)每次让 pre 的 next 指向 cur ,实现一次局部反转
(3)局部反转完成之后, pre 和 cur 同时往前移动一个位置
(4)循环上述过程,直至 pre 到达链表尾部
图解:
代码展示:
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: # 返回ListNode def ReverseList(self, pHead): # write code here # 空链表或只有一个节点得链表 if not pHead&nbs***bsp;not pHead.next: return pHead cur = pHead pre = None # 循环移动curent和pre,移动过程中反转 curent.next=pre while cur: next_node = cur.next cur.next = pre pre = cur cur = next_node return pre
复杂度分析:
时间复杂度O(N):N表示链表长度,双指针一次遍历
空间复杂度O(1):常数大小空间指针
算法思想二:递归
解题思路:
递归上来就先写终止条件:如果head为空或者head.next为空,返回head
(1)新头结点 res 指向尾结点,此处进入递归,递归一直到遍历到尾结点时才会返回
(2)每一层递归,该层递归中的 head 会让下一个节点指向自己,head.next.next = head;然后head自己指向空。以此达到反转的目的。
(3)返回新链表的头结点newHead
(1)新头结点 res 指向尾结点,此处进入递归,递归一直到遍历到尾结点时才会返回
(2)每一层递归,该层递归中的 head 会让下一个节点指向自己,head.next.next = head;然后head自己指向空。以此达到反转的目的。
(3)返回新链表的头结点newHead
代码展示:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode res = ReverseList(head.next);
head.next.next = head;
head.next = null;
return res;
}
} 复杂度分析:
时间复杂度O(N):N表示链表长度
空间复杂度O(N):递归机制的实现需要借助于栈,该程序中递归栈的深度为N-1,所以空间复杂度为线性。
算法思路三:使用额外栈
解题思路:
新建额外的新栈 stack
循环遍历原链表,并将链表元素入栈,遍历结束后,将栈内元素依次出栈并建立链表
图解:
代码展示:
public ListNode ReverseList(ListNode head) {
Stack<ListNode> stack = new Stack<>();
//把链表节点全部摘掉放到栈中
while (head != null) {
stack.push(head);
head = head.next;
}
if (stack.isEmpty())
return null;
ListNode node = stack.pop();
ListNode dummy = node;
//栈中的结点全部出栈,然后重新连成一个新的链表
while (!stack.isEmpty()) {
ListNode tempNode = stack.pop();
node.next = tempNode;
node = node.next;
}
//最后一个结点就是反转前的头结点,一定要让他的next
//等于空,否则会构成环
node.next = null;
return dummy;
} 复杂度分析:
时间复杂度O(N):N表示链表长度
空间复杂度O(N):辅助栈空间



京公网安备 11010502036488号