
思路:要做到反转链表,其实要做的就是将节点的 next 从指向后一个节点改为指向前一个节点。
方法一:迭代
/*** Definition for singly-linked list.* class ListNode {* val: number* next: ListNode | null* constructor(val?: number, next?: ListNode | null) {* this.val = (val===undefined ? 0 : val)* this.next = (next===undefined ? null : next)* }* }*/function reverseList(head: ListNode | null): ListNode | null {// 将节点的 next 从指向后一个节点改为指向前一个节点let prev: ListNode | null = nulllet current: ListNode | null = headwhile(current) {// 使用一个变量保存当前节点的下一个节点const tmp = current.next// 将当前节点的 next 指向前一个节点current.next = prevprev = currentcurrent = tmp}return prev}
复杂度分析:
- 时间复杂度:
- 空间复杂度:
方法二:递归
递归的思想就是将一个过程拆分成一个个更小的过程。
假设链表没有节点或者只有一个节点,那么就应该直接返回传入的 head :
function reverseList(head: ListNode | null): ListNode | null {// 链表没有元素或者只有一个元素的情况if (head === null || head.next === null) {return head;}}
接下来我们假设链表只有两个节点,那么在前面的处理基础之上,它应该加上第二个节点的 next 指向第一个节点,而第一个节点的 next 指向 null 的操作,并且返回链表最后一个节点:
function reverseList(head: ListNode | null): ListNode | null {if (head === null || head.next === null) {return head;}// 当链表只有两个元素的情况// 将第二个节点的 next 指向第一个节点head.next.next = head;// 将第一个节点的 next 指向 nullhead.next = null;return head.next.next}
当链表有两个以上的节点的时候,函数的返回值应返回最后一个节点,而最后一个节点可以通过递归得到。当上面的处理过程再加上通过递归得到最后一个节点,就是本道题目的递归方法题解:
/*** Definition for singly-linked list.* class ListNode {* val: number* next: ListNode | null* constructor(val?: number, next?: ListNode | null) {* this.val = (val===undefined ? 0 : val)* this.next = (next===undefined ? null : next)* }* }*/function reverseList(head: ListNode | null): ListNode | null {// 当为空链表,或者链表只有一个的时候,直接返回 headif (head === null || head.next === null) {return head}const p = reverseList(head.next)head.next.next = head;head.next = null;return p}
上面的递归操作,放在操作当前链表节点操作之前,所以设置当前节点后一个节点的 next 以及当前节点的 next 是从链表的最后一个节点开始的。
假设链表为 1 -> 2 -> 3 -> 4 -> 5,会有一下过程:
- 当前操作节点为 5 时,函数返回 5 这个节点的引用。
- 当前操作节点为 4 时,节点 5 的 next 设置为 4 的引用,而 4 的 next 设置为 null,并返回 5 节点的引用。
- 当前操作节点为 3 时,节点 4 的 next 设置为 3 的引用,而 3 的 next 设置为 null,并返回 5 节点的引用。
- 当前操作节点为 2 时,节点 2 的 next 设置为 3 的引用,而 2 的 next 设置为 null,并返回 5 节点的引用。
- 当前操作节点为 1 时,节点 1 的 next 设置为 2 的引用,而 1 的 next 设置为 null,并返回 5 节点的引用。
复杂度分析:
- 时间复杂度:
- 空间复杂度:
