牛客题霸传送门:点击
-
NC78-反转链表
描述:输入一个链表,反转链表后,输出新链表的表头。链接:点击
示例:
输入 {1,2,3}返回值 {3,2,1}
题解:
1.迭代版本:
分析:因为是单链表,所以我们在迭代的时候前驱节点不能直接获取,我们需要一个额外的变量来保存前驱节点。然后改变当前节点的next前驱节点,同时保存后继节点。
空间复杂度:O(1)。
时间复杂度:O(n)。
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode reverseList(ListNode head) { ListNode pre = null; ListNode curr = head; while (curr != null) { ListNode next = curr.next; curr.next = pre; pre = curr; curr = next; } return pre; } }
2.递归
分析:先分析 reverseList 函数的功能:翻转一个链表,并返回新链表的头节点(原链表的尾节点)。所以我们可以先递归处理 reverseList,将以head.next为头节点的链表翻转,并得到原链表的尾节点,此时head.next是新链表的尾节点,我们令它的next指向head,并将head.next指向空即可将整个链表翻转。
空间复杂度:O(n)。
时间复杂度:O(n)。
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ class Solution { public ListNode ReverseList(ListNode head) { return reverse(head, null); } private ListNode reverse(ListNode curr, ListNode pre) { if (curr == null) {return pre;} ListNode next = curr.next; curr.next = pre; return reverse(next, curr); } }
3.递归优化版本
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ class Solution { private ListNode listHead; public ListNode ReverseList(ListNode node) { if (node == null) return null; if (node.next == null) { listHead = node; return listHead; } ReverseList(node.next); node.next.next = node; node.next = null; return listHead; } }
户枢不蠹,流水不腐