题目描述(简单难度)

206. Reverse Linked List - 图1

单链表倒置。

之前在 第 2 题 大数相加的时候已经分享过了,这里直接贴过来。

解法一迭代

首先看一下原链表。

206. Reverse Linked List - 图2

总共需要添加两个指针,prenext

初始化 pre 指向 NULL

206. Reverse Linked List - 图3

然后就是迭代的步骤,总共四步,顺序一步都不能错。

  • next 指向 headnext ,防止原链表丢失

    206. Reverse Linked List - 图4

  • headnext 从原来链表脱离,指向 pre

    206. Reverse Linked List - 图5

  • pre 指向 head

    206. Reverse Linked List - 图6

  • head 指向 next

    206. Reverse Linked List - 图7

一次迭代就完成了,如果再进行一次迭代就变成下边的样子。

206. Reverse Linked List - 图8

可以看到整个过程无非是把旧链表的 head 取下来,添加的新链表头部。代码怎么写呢?

  1. next = head -> next; //保存 head 的 next , 以防取下 head 后丢失
  2. head -> next = pre; //将 head 从原链表取下来,添加到新链表上
  3. pre = head;// pre 右移
  4. head = next; // head 右移

接下来就是停止条件了,我们再进行一次循环。

206. Reverse Linked List - 图9

可以发现当 head 或者 next 指向 null 的时候,我们就可以停止了。此时将 pre 返回,便是逆序了的链表了。

  1. public ListNode reverseList(ListNode head) {
  2. if (head == null)
  3. return null;
  4. ListNode pre = null;
  5. ListNode next;
  6. while (head != null) {
  7. next = head.next;
  8. head.next = pre;
  9. pre = head;
  10. head = next;
  11. }
  12. return pre;
  13. }

解法二递归

  • 首先假设我们实现了将单链表逆序的函数,ListNode reverseListRecursion(ListNode head) ,传入链表头,返回逆序后的链表头。

  • 接着我们确定如何把问题一步一步的化小,我们可以这样想。

    head 结点拿出来,剩下的部分我们调用函数 reverseListRecursion ,这样剩下的部分就逆序了,接着我们把 head 结点放到新链表的尾部就可以了。这就是整个递归的思想了。

206. Reverse Linked List - 图10

  • head 结点拿出来

    206. Reverse Linked List - 图11

  • 剩余部分调用逆序函数 reverseListRecursion ,并得到了 newhead

    206. Reverse Linked List - 图12

  • 将 2 指向 1 ,1 指向 null,将 newhead 返回即可。

    206. Reverse Linked List - 图13

  • 找到递归出口

    当然就是如果结点的个数是一个,那么逆序的话还是它本身,直接 return 就够了。怎么判断结点个数是不是一个呢?它的 next 等于 null 就说明是一个了。但如果传进来的本身就是 null,那么直接找它的 next 会报错,所以先判断传进来的是不是 null ,如果是,也是直接返回就可以了。

  1. public ListNode reverseList(ListNode head) {
  2. ListNode newHead;
  3. if (head == null || head.next == null) {
  4. return head;
  5. }
  6. newHead = reverseList(head.next); // head.next 作为剩余部分的头指针
  7. // head.next 代表新链表的尾,将它的 next 置为 head,就是将 head 加到末尾了。
  8. head.next.next = head;
  9. head.next = null;
  10. return newHead;
  11. }

关于链表的题,记住更改指向的时候要保存之前的节点,不然会丢失节点。

windliang wechat

添加好友一起进步~

如果觉得有帮助的话,可以点击 这里 给一个 star 哦 ^^

如果想系统的学习数据结构和算法,强烈推荐一个我之前学过的课程,可以点击 这里 查看详情