206. 反转链表
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
思路:
头插法。共三个关键结点,如图:

Java代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
//思路:不断让后面的结点连到dummy的后面,结点遍历完毕,也就反转完毕了
if(head == null) return head;
//由于用的是头插法,即后面的节点需要插在当前头节点之前,所以声明一个虚拟头节点
ListNode dummy = new ListNode(0);
dummy.next = head;
//表示本次要插入到dummy后的结点,即插入到原始链表的头节点位置
ListNode cur = dummy.next.next;
//tail指向一直不变,改变的是tail.next,用于将已经反转的部分链表和剩余还需要反转的链表相连
ListNode tail = head;
while(cur != null){
//记住下一个需要头插的节点,避免等下cur.next改变指向,就找不到原来的cur.next了
ListNode nxt = cur.next;
cur.next = dummy.next;
dummy.next = cur;
tail.next = nxt;//将已经反转的部分链表和剩余还需要反转的链表相连
cur = nxt;//下一个要头插的节点
}
return dummy.next;
}
}

Go代码
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
// 经典头插法,cur一直指着需要头插的节点
if head == nil || head.Next == nil {
return head
}
dummy := &ListNode{}
dummy.Next = head
cur := dummy.Next.Next // cur从一开始就指着需要头插的节点,表示本次要插入到dummy后的结点
tail := dummy.Next //tail指向一直不变,改变的是tail.next,用于将已经反转的部分链表和剩余还需要反转的链表相连
for cur != nil {
tail.Next = cur.Next //将已经反转的部分链表和剩余还需要反转的链表相连
cur.Next = dummy.Next
dummy.Next = cur
cur = tail.Next //下一个要头插的节点
}
return dummy.Next
}

本文解析如何使用迭代和递归方法解决单链表反转问题,通过Java代码实例演示了头插法的技巧,并介绍了关键步骤和思路。
2175

被折叠的 条评论
为什么被折叠?



