链表7:超高频面试题——链表反转之一

Posted 纵横千里,捭阖四方

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表7:超高频面试题——链表反转之一相关的知识,希望对你有一定的参考价值。

链表反转是一个出现频率特别高的算法题,笔者过去这些年面试,至少遇到过七八次。其中更夸张的是曾经两天写了三次,上午YY,下午金山云,第二天快手。链表反转在各大高频题排名网站也长期占领前三。比如牛客网上这个No 1 好像已经很久了。

另外很多题目也都要用它来做基础, 例如指定区间反转、链表K个一组翻转。还有一些在内部的某个过程用到了反转,例如两个链表生成相加链表。还有一种是链表排序的,也是需要移动元素之间的指针,难度与此差不多。从今天开始,我们用3篇来专门研究一下这几个问题。第一篇,介绍反转的3种实现方法。第二篇介绍反转的几种变形,第三篇介绍两个链表生成相加的链表。

首先我们看一下题目要求:

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

如下图:

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

1.实现

这个题目的关键点是如果再定义一个新链表,会对内存空间造成浪费,比较好的方式是将每个结点的指向都反过来就行,也就是下面这个样子:

那这里的问题就是如何准确的记录并调整指针,代码也不算很复杂:

class Solution {    public ListNode reverseList(ListNode head) {        ListNode prev = null;        ListNode cur = head;        ListNode temp = null;        while (cur != null) {            temp = cur.next;// 保存下一个节点            cur.next = prev;            prev = cur;            cur = temp;        }        return prev;    }}

建议你自己在纸上画画图、想一想,如果能想明白就不必看我下面的解释了。

二、迭代法解析

上面迭代法不算复杂,一般是能想清楚的,但是面试的时候可能会突然卡壳,怎么也搞不清楚指针到底怎么处理。我们可以通过图示来看一下:

在上图中,我们用cur来表示旧链表被访问的位置,pre表示新链表的表头。注意图中箭头方向,cur和pre都是两个表的表头,每移动完一个结点之后,我们必须准确知道两个链表的表头。

cur是需要接到pre的,那该怎么知道其下一个结点5呢?

很显然仅仅靠pre和cur是不够的,我们需要一个temp结点来临时保存cur的下一个指针(图中的5),然后将cur的next指针指向pre,然后将cur赋值给pre,最后将temp再赋值给cur。

上面这个过程不仅严密,而且顺序都不能错。也就是这几行代码:

           temp = cur.next;// 保存下一个节点            cur.next = prev;            prev = cur;            cur = temp;

 三.递归方法实现

这个题目还可以使用递归实现的,但是笔者强烈建议你将前面的方法想清楚,写清楚,最好闭着眼睛就能写,递归的方式就不考虑了。

因为每次cur移动之后仍然是旧的链表表头,prev移动之后仍然是新链表的表头。我们可以使用相同的操作继续处理,所以这里我们可以通过递归来做:

// 递归 class Solution {    public ListNode reverseList(ListNode head) {        return reverse(null, head);    }    private ListNode reverse(ListNode prev, ListNode cur) {        if (cur == null) {            return prev;        }        ListNode temp = null;        temp = cur.next;// 先保存下一个节点        cur.next = prev;// 反转        // 更新prev、cur位置        prev = cur;        cur = temp;        return reverse(prev, cur);    }} 

以上是关于链表7:超高频面试题——链表反转之一的主要内容,如果未能解决你的问题,请参考以下文章

给秋招加点料——Hot15道高频算法面试题!

大厂面试高频算法题,这10道题必须拿捏!

排序奇升偶降链表-链表拆分反转归并-字节跳动高频题

微软面试题: LeetCode 206. 反转链表 出现次数:3

143. 重排链表-链表拆分+反转+合并-字节跳动高频题

92. 反转链表 II-字节跳动高频题