Java 详细分析四个经典链表面试题

前言:

上一章更到了链表,虽然知道了什么是链表,链表的结构是怎么样的,但这是远远不够的,我们只清楚了点皮毛,如果让你做题你还是会无从下手,所以我们必须多做题,在做题的过程中慢慢的我们就会觉得一切都很简单。下面我们就来做几道经典的链表面试题!!!!!!

第一题

题目:反转一个单链表

每个节点是不变的,只是修改当前每个节点的指向

看图分析:

问题分析:

每个节点是不变的,只需要修改当前每个节点的指向,第一个节点指向变成null,第二个节点的指向是第一个节点。

问题讲解:

我们需要定义四个节点变量

head变量等于头节点

cur = head

prev = null

curNext = cur.next

第一步:curNext = cur.next

第二步:cur.next = prev

第三步:prev = cur

第四步:cur = curNext

我们看一下图解是如何走的

第一步:curNext = cur.next

第二步:cur.next = prev

第三步: prev = cur

第四步: cur = curNext

这四步让它是一个循环,我们再走一个循环给大家看

第五步: curNext = cur.next

第六步: cur.next = prev

第七步: prev = cur

第八步: cur = curNext

这样两个循环下来我想大家看的就很明白了,那既然是循环肯定会有终止条件,所以我们可以看一下,当cur走到最后一个字节的时候,我们仍然需要 cur.next =  prev,再往后走的话cur就为null了,为null的时候就反转结束了。所以我们循环的终止条件就是cur != null。另外我们还需要判断一直指向头节点的head为不为null,如果为null的话就是没有这个链表,直接返回null就可以了。反转完成后最后一个节点就变成了头节点,所以我们返回prev就可以了、那我们就可以来写代码了。

代码实现:

lass Solution {
    public ListNode reverseList(ListNode head) {
         if (head == null) {
            return null;
        }
        ListNode cur = head;
        ListNode prev = null;

        while (cur != null) {
            ListNode cutNext = cur.next;
            cur.next = prev;
            prev = cur;
            cur = cutNext;
        }
        return prev;

    }
}

力扣

https://leetcode-cn.com/problems/reverse-linked-list/description/

题目链接在上面,大家一定打开链接自己做一下。

第二题

题目:给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。

画图分析:

问题分析:奇数的话返回中间的节点,偶数的话返回第二个中间节点,也就是说偶数返回第三个。

问题讲解:

同样的,我们来定义两个引用变量

fast,slow两个引用变量都等于head头节点

如图:

我们让fast一次走两步,slow一次走两步,奇数情况:fast.next为null,slow所在的就是中间节点位置 。偶数情况:fast为null,low所在的就是中间节点位置 。原因是为什么呢?两个同时走,fast的速度是slow的两倍,那么路程也是两倍,一个走到终点了,那么另一个就是走了路程的一半。有这样的思路我们就可以来写代码了 ,同样的先要判断一下链表是不是为null,为null直接返回null就好了

代码实现:

class Solution {
    public ListNode middleNode(ListNode head) {
        if(head == null){
            return null;
        }
            ListNode fast = head;
            ListNode slow = head;
            while(fast != null && fast.next != null ){
                fast = fast.next.next;
                slow = slow.next;
            }
            return slow;
        }
}

力扣

https://leetcode-cn.com/problems/middle-of-the-linked-list/description/

第三题

题目:输入一个链表,输出该链表中倒数第k个结点

画图分析:

问题讲解:

同样的,我们来定义两个引用变量

fast,slow两个引用变量都指向头节点

如图:

如果我们要找倒数第K个,从第K个到倒数第1个需要走K-1步,所以我们先让fast走K-1步,当走完K-1步,fast指向的是倒数第一个时候,那么slow就是我们要找的倒数第K给,如果fast走完K-1步,fast指向的不是倒数第一个,那么这个时候我们让fast和slow一起往后走,他们始终差了K-1步,当fast 走到倒数第一个的时候,这个时候slow所指向的节点就是我们要找的倒数第K个。这里K我们也要判断一下,如果K<=0 或者 k>链表的长度,我们直接返回null就可以了。

代码实现:

public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(k <= 0 || head == null){
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        while(k-1 != 0){
            fast = fast.next;
            if(fast == null){
                return null;
            }
            k--;
        }
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;

    }
}

题目链接

第四题

题目:将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

画图分析:这是我们的两个链表

问题讲解:

同样的,先定义两个引用变量headA和headB分别指向两个链表的头节点。

定义一个虚拟节点,假设叫newHead,在定义一个引用变量tmp等于newHead

首先我们先来比较headA和headB的大小,如果headA.val<headB.val,那么就让tmp.next等于headA

因为12小,那么就让headA = headA.next,如果后面再找到比12大数字就要放在12的后头,所以我们让tmp = tmp.next,

这个时候再比较headA和headB, 如果headA.val>headB.val,那么就是让tmp.next = headB,再让headB = headB.next,tmp = tmp.next

这样就构成了我们的一个循环,当headA和headB都不为null的时候我们才能继续循环,当循环结束,要么headA为null,要么headB为null,当headA为null,我们让tmp.next = headB,当headB为null,我们让tmp.next = headA,

代码实现:

lass Solution {
    public ListNode mergeTwoLists(ListNode headA, ListNode headB) {
 ListNode newhead = new ListNode(-1);
       ListNode tmp = newhead;
       while (headA != null && headB != null) {
           if (headA.val < headB.val) {
               tmp.next = headA;
               headA = headA.next;
               tmp = tmp.next;
           } else {
               tmp.next = headB;
               headB = headB.next;
               tmp = tmp.next;
           }
       }
           if(headA == null){
               tmp.next = headB;
           }
           if(headB == null){
               tmp.next = headA;
           }
       return newhead.next;

    }
}

力扣

https://leetcode-cn.com/problems/merge-two-sorted-lists/description/

因为时间原因:今天就先打卡这4道面试题,这4道面试题都是比较经典的面试题,对我们链表这块的学习会很有帮助。学习数据结构就是要多刷题,这样你才能完全掌握数据结构这门知识。今天太晚了,明天再继续给大家更面试题吧。有任何疑问大家都可以私信我,有问题欢迎大家指出来,我都会虚心学习的,希望可以和大家一起进步。

到此这篇关于Java 详细分析力扣链表面试题的文章就介绍到这了,更多相关Java 链表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java 链表实战真题训练

    目录 1.删除值为val的所有节点 2.反转链表 3.返回链表中间节点 4.返回链表第K个节点 5.合并有序链表 6.按值分割链表 7.判读回文链表 8.找两个链表的公共节点 9.判断成环链表 10.返回成环链表的入口 每个题目后面有放对应题目的OJ链接,大家可以先了解一下解题思路,然后自己先去做一下. 1.删除值为val的所有节点 删除链表中等于给定值val的所有节点.[OJ链接] 定义两个指针prev.cur,cur指向头节点的下一个节点,prev始终指向cur的前一个结点(方便删除节点).

  • Java 数据结构与算法系列精讲之环形链表

    目录 概述 链表 环形链表 环形链表实现 Node类 insert方法 remove方法 main 完整代码 概述 从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章. 链表 链表 (Linked List) 是一种递归的动态数据结构. 链表以线性表的形式, 在每一个节点存放下一个节点的指针. 链表解决了数组需要先知道数据大小的缺点, 增加了节点的指针域, 空间开销较大. 链表包括三类: 单向链表 双向链表 循环链表 环形链表 环形链表 (Circular Linked Li

  • Java 深入分析链表面试实例题目

    目录 链表面试题一 问题描述: 问题分析: 问题讲解: 代码实现: 链表面试题二 问题描述: 问题分析: 问题讲解: 代码实现: 链表面试题一 判断链表是否是回文结构. 问题描述: 兄弟们,看图理解什么是链表的回文结构: 回文结构:正着读12 -> 23 ->34,倒着读12->23->34 奇数偶数都可以: 问题分析: 要判断是不是回文结构,那么我们就要遍历链表,一个从前往后走,一个从后往前走,对应的val值要相同,那么我们就必须修改链表的指向,这里就要用到快慢指针帮我们找到中间

  • Java 数据结构与算法系列精讲之单向链表

    目录 概述 链表 单向链表 单向链表实现 Node类 add方法 remove方法 get方法 set方法 contain方法 main 完整代码 概述 从今天开始, 小白我将带大家开启 Jave 数据结构 & 算法的新篇章. 链表 链表 (Linked List) 是一种递归的动态数据结构. 链表以线性表的形式, 在每一个节点存放下一个节点的指针. 链表解决了数组需要先知道数据大小的缺点, 增加了节点的指针域, 空间开销较大. 链表包括三类: 单向链表 双向链表 循环链表 单向链表 单向链表

  • Java实现单链表基础操作

    关于链表 链表是有序的列表链表是以节点的方式来存储每个节点包含data域,next域(指向下一个节点)分带头节点的链表和没有头节点的链表 定义一个节点: package linkedQueue; public class HeroNode { public int no; public String name; public String nickname; public HeroNode next;//指向下一个节点 public HeroNode(int no, String name, S

  • Java实现顺序表和链表结构

    目录 前言: 顺序表 定义: 实现方法: 代码实现: 链表 定义: 分类: 实现方法: 代码实现: 顺序表 & 链表 总结 前言: 线性表(linear list)是n个具有相同特性的数据元素的有限序列. 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表.链表.栈.队列.字符串. 顺序表 定义: 用一段物理地址连续的存储单元依次存储数据元素的线性结构(逻辑上连续,物理上也连续) (1)静态顺序表:使用定长数组存储. (2)动态顺序表:使用动态开辟的数组存储 [注意]静态顺序表的定长数

  • Java 精炼解读数据结构的链表的概念与实现

    目录 前言: 一.什么是链表 链表的概念 链表的结构 链表如何存储数据 链表的实现   穷举法创建链表 打印链表 查找是否包含关键字key是否在单链表当中  得到单链表的长度: 头插法 尾插法 任意位置插入,第一个数据节点为0号下标 删除第一次出现关键字为key的节点 删除所有值为key的节点 总结: 前言: 顺序表的问题及思考 1. 顺序表中间/头部的插入删除,时间复杂度为O(N) 2. 增容需要申请新空间,拷贝数据,释放旧空间.会有不小的消耗. 3. 增容一般是呈2倍的增长,势必会有一定的空

  • java使用单向链表解决数据存储自定义排序问题

    目录 表设计 1. 新增一条记录 2. 修改排序 3. 删除 代码实现 1. 简单对象 2. 对数据按照 nextId 排序 3. 输出结果 表设计 CREATE TABLE `test` ( `id` bigint NOT NULL COMMENT '主键id', `name` varchar(50) COLLATE NOT NULL COMMENT '名称', `next_id` bigint DEFAULT NULL COMMENT '指向下一个节点的主键id', ) ; 1. 新增一条记

  • Java 详细分析四个经典链表面试题

    前言: 上一章更到了链表,虽然知道了什么是链表,链表的结构是怎么样的,但这是远远不够的,我们只清楚了点皮毛,如果让你做题你还是会无从下手,所以我们必须多做题,在做题的过程中慢慢的我们就会觉得一切都很简单.下面我们就来做几道经典的链表面试题!!!!!! 第一题 题目:反转一个单链表 每个节点是不变的,只是修改当前每个节点的指向 看图分析: 问题分析: 每个节点是不变的,只需要修改当前每个节点的指向,第一个节点指向变成null,第二个节点的指向是第一个节点. 问题讲解: 我们需要定义四个节点变量 h

  • Java详细分析讲解HashMap

    目录 1.HashMap数据结构 2.HashMap特点 3.HashMap中put方法流程 java集合容器类分为Collection和Map两大类,Collection类的子接口有Set.List.Queue,Map类子接口有SortedMap.如ArrayList.HashMap的继承实现关系分别如下 1.HashMap数据结构 在jdk1.8中,底层数据结构是“数组+链表+红黑树”.HashMap其实底层实现还是数组,只是数组的每一项都是一条链,如下 当链表过长时,会严重影响HashMa

  • Java详细分析讲解自动装箱自动拆箱与Integer缓存的使用

    目录 1. 前言 2. 包装类 3. 自动装箱与自动拆箱 4. Interger缓存 5. 回答题目 1. 前言 自动装箱和自动拆箱是什么?Integer缓存是什么?它们之间有什么关系? 先来看一道题目. Integer a = new Integer(1); Integer b = new Integer(1); System.out.println(a==b); Integer c = 1; Integer d = 1; System.out.println(c==d); Integer e

  • Java详细分析String类与StringBuffer和StringBuilder的使用方法

    目录 String类基本概念 String字符串的存储原理 String类的常用构造方法 String类中常用方法 StringBuffer类 StringBuilder类 String类基本概念 String类属于引用数据类型,不属于基本数据类型. 在Java中只要是" "(双引号)中的,都是String对象. java中规定,双引号中的字符串是不可变的,也就是说"abc"自出生到死亡都不可能变成"abcd",也不能变成"ab&quo

  • Java详细分析sleep和wait方法有哪些区别

    目录 一.sleep和wait方法的区别 二.wait方法 wait方法的使用 wait结束等待的条件 三.notify和notifyAll方法 一.sleep和wait方法的区别 根本区别:sleep是Thread类中的方法,不会马上进入运行状态,wait是Object类中的方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程 释放同步锁:sleep会释放cpu,但是sleep不会释放同步锁的资源,wait会释放同步锁资源 使用范围: slee

  • Java详细分析讲解泛型

    目录 1.泛型概念 2.泛型的使用 2.1泛型类语法 2.2泛型方法语法 2.3泛型接口语法 2.4泛型在main方法中的使用 3.擦除机制 4.泛型的上界 5.通配符 5.1通配符的上界 5.2通配符的下界 6.包装类 6.1装箱和拆箱 1.泛型概念 泛型就是将类型参数化 所谓类型参数化就是将类型定义成参数的形式,然后在使用此类型的时候的时候再传入具体的类型 到这我们可以看出来:泛型在定义的时候是不知道具体类型的,需要在使用的时候传入具体的类型,泛型可以用在类.接口和方法中,这样做的好处是一个

  • Java详细分析梳理垃圾回收机制

    目录 Java语言的垃圾回收 1.垃圾回收机制的基本概念 2.Java垃圾回收机制的好处 3.Java垃圾回收机制的特点 总结 Java语言的垃圾回收 1.垃圾回收机制的基本概念 问:1.什么是Java垃圾回收? 答:在Java语言的生命周期中,Java运行环境提供了一个系统的垃圾回收器线程,负责自动回收那些没有引用与之相连的对象所占用的内存.这种清楚无用对象进行内存回收的过程叫做垃圾回收. 问:2.Java垃圾回收的作用是什么? 答:垃圾回收是Java语言提供的一种自动内存回收的功能,可以让程

  • Java详细分析连接数据库的流程

    目录 注册驱动程序 创建连接 创建 SQL 语句 执行 SQL 语句 关闭连接 以下 5 个步骤是使用 JDBC 将 Java 应用程序与数据库连接所涉及的基本步骤. 注册驱动程序 创建连接 创建 SQL 语句 执行 SQL 语句 关闭连接 注册驱动程序 它首先是创建 JDBC 连接的重要部分.JDBC API 提供了一种Class.forName()用于显式加载驱动程序类的方法.例如,如果我们要加载 jdbc-odbc 驱动程序,那么我们将其称为如下. 使用 JDBC-ODBC 驱动程序注册的

  • Java详细分析Lambda表达式与Stream流的使用方法

    目录 Lambda Stream流 Lambda Lambda 表达式是一个匿名函数,我们可以把 lambda 表达式理解为一段可以传递的代码(将代码段像数据一样传递).使用它可以写出更简洁, 更灵活的代码.作为一种更紧凑的代码风格,使 java 语言的表达式能力得到的提升. 我们可以知道, Lambda表达式是为简化语法而存在的 ArrayList<String> list = new ArrayList<>(); list.add("a"); list.ad

  • Java详细分析LCN框架分布式事务

    目录 2PC两阶段提交协议 LCN LCN基本实现原理 搭建全局协调者 使用LCN解决分布式事务问题 源码分析 2PC两阶段提交协议 分布式事务通常采用2PC协议,全称Two Phase Commitment Protocol.该协议主要为了解决在分布式数据库场景下,所有节点间数据一致性的问题.分布式事务通过2PC协议将提交分成两个阶段: 阶段一为准备(prepare)阶段.即所有的参与者准备执行事务并锁住需要的资源.参与者ready时,向transaction manager报告已准备就绪.

随机推荐