反转链表

力扣第206题

我们不只是简单的学习(背诵)一个数据结构,而是要分析他的思路,以及为什么要有不同的指针等等

非递归方式:

思路分析:首先要链表有个头指针没有任何问题

然后,我们要将1的下一个节点指向空,这样才能将其反转过来,但是这个时候我们发现和下一个节点2失去了联系

所以我们要有一个指针,在1还没有将next指向空前,记录下2的位置。所以我们用一个next指针记录2。并为了好理解,将head改名为cur代表当前节点。

因此,我们只要将cur的指向下一个节点的指针指向空之后,便将cur和next指针同时向后移动。

不过这样我们发现,我们cur和前面的节点失去了联系,就不能将节点2指向1了,所以我们还要有一个指针负责记录前一个节点,我们就叫它pre吧,那么再来考虑pre指针最开始应该放在哪呢,其实只要指向最左边的那个NULL就好了。

因此我们刚刚是将1指向NULL,现在改成将cur指向pre即可,就像这样。

然后我们就可以将这三个指针都向后移动,重复上一步和本步操作,直到cur为null结束即可。

递归方式:

首先是写出递归的最后答案,也就是所谓的递归出口,毫无疑问是返回第一个节点head

if (head == null || head.next==null)
    return head;

再调用一次递归函数

reverseListRecursive(head.next);

直接从宏观的角度上看,肯定是将head.next之后的所有节点都反转过来了,就像下图所示,其中1被挡住了不要在意。

重点来了,如何将最后的节点2指向节点1,并将节点1指向空?

其实用两行代码实现即可,将head.next(节点2).next(NULL)指向节点1,也就是 = head即可

然后再将节点1指向空,也即head.next = null;

 head.next.next = head;
head.next = null;

力扣答案总结:

我们来具体实现一下吧,其中的reverseList内的代码即是力扣答案

/**
* @Author: 翰林猿
* @Description: 反转链表
**/
public class ReverseListNode {
   //非递归方式
   public ListNode reverseList(ListNode head) {
       //初始化三个指针,其中latter要在过程中指定,因为有可能cur为空,导致latter为空
       ListNode pre = null;
       ListNode cur = head;
       while (cur != null) {
           ListNode latter = cur.next;
           //将cur指向pre
           cur.next = pre;
           //三个指针都向后移动,其中pre和cur在这里移动,latter在第一句会自行移动。
           pre = cur;
           cur = latter;
      }
       return pre;
  }
   //递归方式
   public ListNode reverseListRecursive(ListNode head) {
       if (head == null || head.next==null)
           return head;
       ListNode rev = reverseListRecursive(head.next);     //最后会获取到head
       head.next.next = head;
       head.next = null;
       return rev;
  }
   public static void main(String[] args) {
       ListNode head = new ListNode(1);
       head.next = new ListNode(2);
       head.next.next = new ListNode(3);
       head.next.next.next = new ListNode(4);
       head.next.next.next.next = new ListNode(5);

       ListNode node = new ReverseListNode().reverseList(head);
       System.out.println("反转后的第一个节点值应当为5 = "+node.val);

       ListNode node2 = new ReverseListNode().reverseListRecursive(head);
       System.out.println("递归反转后的第一个节点值应当为5 = "+node.val);
  }
}


class ListNode {
   int val;
   ListNode next;
   ListNode() {
  }
   ListNode(int val) {
       this.val = val;
  }
   ListNode(int val, ListNode next) {
       this.val = val;
       this.next = next;
  }
}

反转链表 Java版 图文并茂思路分析带答案(力扣第206题)的更多相关文章

  1. 《剑指offer》面试题16 反转链表 Java版

    (输入链表的头节点,反转链表) 书中方法:对于一个链表,我们只能从头往后遍历,如果要反转,我们需要更改当前节点的next域指向前一个节点,此时链表断开,为了能继续修改下一个节点的next域,我们还要维 ...

  2. PAT 1025 反转链表 (25)(STL-map+思路+测试点分析)

    1025 反转链表 (25)(25 分) 给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转.例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4:如果K为4, ...

  3. 剑指Offer:面试题16——反转链表(java实现)

    问题描述 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的链表的头结点.链表结点如下: public class ListNode { int val; ListNode next = n ...

  4. 15.反转链表 Java

    题目描述 输入一个链表,反转链表后,输出新链表的表头. 思路 本题的关键就是在于对next域的赋值,同时对下一个节点进行保存,然后对把下一个节点赋给新的节点,这样依次循环完所有的节点.每次使新插入的节 ...

  5. PAT-basic-1025 反转链表 java c++

    一.题目 给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转.例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4:如果 K 为 4, ...

  6. 《剑指offer》面试题5 从尾到头打印链表 Java版

    书中方法一:反转应该立刻想到栈,利用一个栈完成链表的反转打印,但是用了额外的O(n)空间. public void printFromTail(ListNode first){ Stack<Li ...

  7. 《剑指offer》面试题17 合并两个排序的链表 Java版

    我的方法:新初始化一个链表头,比较两个链表当前节点的大小,然后连接到该链表中.遍历两个链表直到null为止. public ListNode merge(ListNode first, ListNod ...

  8. 用递归调用实现字符串反转(java版)

    写一个函数,输入int型,返回整数逆序后的字符串.如:输入123,返回“321”. 要求必须用递归,不能用全局变量,输入必须是一个参数,必须返回字符串. public static String re ...

  9. 吐血整理!2万字Java基础面试题(带答案)请收好!

    熬夜整理了这么多年来的Java基础面试题,欢迎学习收藏,手机上可以点击这里,效果更佳https://mp.weixin.qq.com/s/ncbEQqQdJo0UaogQSgA0bQ 1.1 Hash ...

  10. 50道Java线程面试题分析及答案

    下面是Java线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程?线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程 ...

随机推荐

  1. ServletContext 详解(转载)

    转载:https://www.cnblogs.com/zjdxr-up/p/7761813.html ServletContext,是一个全局的储存信息的空间,服务器开始,其就存在,服务器关闭,其才释 ...

  2. day49:django:wsgrief&模板渲染Jinjia2&django的MTV/MVC框架&创建/启动一个django项目

    目录 1.自定义web框架wsgiref版 2.自定义web框架wsgiref版-优化版 3.模板渲染JinJa2 4.MTV和MVC框架 5.django:下载安装&创建启动 自定义web框 ...

  3. 【从零开始】Docker Desktop:听说你小子要玩我

    前言 缘由 捡起遗忘的Docker知识 由于本狗近期项目紧任务重,高强度的搬砖导致摸鱼时间下降.在上线项目时,看到运维大神一系列骚操作,docker+k8s的知识如过眼云烟,忘得干净的很.所以想重新恶 ...

  4. 【SpringMVC】(一)

    SpringMVC简介 SpringMVC是Spring的一个后续产品,是Spring的一个子项目 基于原生的Servlet,通过了功能强大的DispatcherServlet,对请求和响应进行统一处 ...

  5. ROS动态调试PID参数

    ROS动态调试PID参数 连接小车 注意:必须在同一区域网 ssh clbrobort@clbrobort 激活树莓派主板 roslaunch clbrobot bringup.launch 打开PI ...

  6. SpringBoot之Mybatis开启SQL记录和Pagehelper

    配置mybatis mybatis: #mapper路径 mapper-locations: classpath:mapper/*.xml configuration: #日志输出 log-impl: ...

  7. ray-分布式计算框架-集群与异步Job管理

    0. ray 简介 ray是开源分布式计算框架,为并行处理提供计算层,用于扩展AI与Python应用程序,是ML工作负载统一工具包 Ray AI Runtime ML应用程序库集 Ray Core 通 ...

  8. Consistency Models终结扩散模型

    最近看到一篇论文,觉得特别有意思,并且在学术界引起了不小的动静,他就是一致性模型,据说图像生成效果快.质量高,并且还可以实现零样本图像编辑,即不进行一些视觉任务训练,可以实现图像超分.修复.上色等功能 ...

  9. 机器学习02-(损失函数loss、梯度下降、线性回归、评估训练、模型加载、岭回归、多项式回归)

    机器学习-02 回归模型 线性回归 评估训练结果误差(metrics) 模型的保存和加载 岭回归 多项式回归 代码总结 线性回归 绘制图像,观察w0.w1.loss的变化过程 以等高线的方式绘制梯度下 ...

  10. NFS共享存储实战

    NFS共享存储实战 目录 NFS共享存储实战 NFS基本概述 为什么要使用共享存储 企业中文件服务器(共享存储) NFS应用场景 集群没有共享存储时 集群有共享存储 NFS实现原理 NFS的函数 本地 ...