【面试算法专栏及回答思考】——反转链表

167 阅读2分钟

这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

img

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:

img

输入:head = [1,2]
输出:[2,1]
示例 3:
输入:head = []
输出:[]
提示:
  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000

**进阶:**链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

解题

解题思路

此题和反转链表题类似,遇到这类的题同学们都可以从两个思路来做相关思考:递归和迭代

首先我们先看递归:

1、递归上来就先写终止条件:我们可定义一个pre和一个curr,分别指指向当前节点的前一个节点和当前节点(头节点)ps:pre不能new一个节点,不然val默认值为0,结果会多出一个0节点,也不能pre.next=head,否则会产生一个环 2、while循环遍历,定义一个node指向curr,(这样curr指向curr.next的时候还可以访问到curr) 先让curr指向下一个节点,接着让node指向pre,反转第一个节点,如何pre继续指向node,跟在curr后面,循环 3、循环条件为curr!=null,否则停止循环。此时pre为第一个节点,所以return pre;

迭代则思路如下:

1、迭代需要三个指针,pre,cur,nxt,分别按顺序指向三个节点

2、三个指针的初始化:pre指向空节点,cur指向头结点head,nxt指向head.next 因为head.next可能不存在,nxt在循环中定义,这样如果head为空就不会进入循环

3、迭代过程

  • nxt指向cur.next
  • cur.next指向pre
  • pre移动到cur位置
  • cur移动到nxt位置

4、当cur为空时,返回pre

代码实现

class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null){
            return head;
        }
        ListNode pre = head;
        ListNode cur = head.next;
        head.next = null;
        ListNode tmp;
        while (cur!=null){
            tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }

        return pre;
    }
}

class Solution {

    ListNode preNode;
    ListNode tail;
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null){
            return head;
        }
        preNode = head;
        nextNode(head.next);
        head.next = null;
        return tail;
    }


    public void nextNode(ListNode node){
        if (node == null){
            tail = preNode;
            return;
        }
        ListNode next = node.next;
        node.next = preNode;
        preNode = node;
        nextNode(next);
    }
}

除此之外,同学们也可以针对这题用辅助栈去试试。今天关于反转链表的思考和解析就到这儿,欢迎同学指出错误,共同进步!