题目描述:
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
思路分析:
-
递归法
该题可以用递归处理。一直递归到最后一个结点,然后翻转最后一个结点,然后翻转倒数第二个结点…返回之前的尾结点,即翻转后的首结点。
参考代码:
public static ListNode reverseList(ListNode head) {
if(head == null || head.next == null)return head;
ListNode root = reverseList(head.next);
head.next.next = head;
head.next = null;
return root;
}
-
迭代法:
设置3个指针pre,curr,next,分别表示前一个结点,当前节点,后一个结点,然后从前到后进行翻转。
参考代码:
public static ListNode reverseList(ListNode head) {
if(head == null || head.next == null)return head;
ListNode pre = null;
ListNode curr = head;
ListNode next = head.next;
while(next != null){
curr.next = pre;
pre = curr;
curr = next;
next = next.next;
}
curr.next = pre;
return curr;
}
补充:
翻转链表的第m个结点到第n个结点
参考代码:
public ListNode reverseBetween(ListNode head, int m, int n) {
if(head == null || head.next == null)return head;
//创建一个伪结点
ListNode dummy = new ListNode(-1);
dummy.next = head;
//找到第m-1个结点
ListNode pre = dummy;//注意:这里从dummy结点开始遍历
for(int i = 1; i < m; i++){
pre = pre.next;
}
ListNode curr = pre.next;
//开始进行翻转:这里是从第m+1个结点开始,到第n个结点,将中间的所有结点插入到pre结点后面:头插法
for(int i = m; i < n; i++){
ListNode next = curr.next;//这里用的局部变量
curr.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dummy.next;
}
(完)