LeetCode - 206、反转链表
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
1 /** 2 * 列表定义 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { val = x; } 7 * } 8 */
解法:头插法
1 class Solution { 2 public ListNode reverseList(ListNode head) { 3 //头插法反转列表 4 ListNode root = new ListNode(0); 5 ListNode next = new ListNode(0); 6 7 while (head != null) { 8 //记录下一个节点的位置 9 next = head.next; 10 //原列表的head.next结点指向反转列表root的下一个结点 11 head.next = root.next; 12 //反转列表root.next指向原列表head,这边已经完成了头插法反转 13 root.next = head; 14 //原列表head后移一位 15 head = next; 16 } 17 return root.next; 18 } 19 }
解法:递归
1 class Solution { 2 public ListNode reverseList(ListNode head) { 3 if (head == null || head.next == null) return head; 4 ListNode p = reverseList(head.next); 5 head.next.next = head; 6 head.next = null; 7 return p; 8 } 9 }
说明:首先本递归方式是从列表尾部开始操作。递归的思路可以从只有三个节点的列表入手。
if (head == null || head.next == null) return head; 递归中找到列表最后一个节点,在下面 p = 这个节点。特别情况:当列表只有一个节点时直接返回
ListNode p = reverseList(head.next); 每次返回的p节点就是原始列表的最后一个节点,代码中也没有对p进行操作操作
head.next.next = head; 每次交换两个节点的顺序
head.next = null; 将原始列表的第一个节点的next置空。反转完成后,原始列表的第一个节点变成新列表的最后一个节点,避免循环列表
return p; 每次返回原始列表的最后一个节点