当前位置: 首页 > news >正文

Java单链表题目

Java链表题目练习

  • 移除链表元素
  • 反转单链表
  • 链表的中间节点
  • 返回倒数第K个节点
  • 合并两个有序列表
  • 判断链表是否回文

学习了知识,就要进行其检验自己是否真正学会,练习题目来加强对知识的理解,今天就来练习一下链表题目


移除链表元素

在这里插入图片描述

目的:就是给定一个数val,删除链表中所有节点值等于val的节点
思路:
就是利用快慢指针进行查找,快的指针找到的话,就让其慢的指针.next = 快指针.next;快指针指向下一个,如果没有找到的话,两个指针同时向后移动,一直保持一个距离

1.就是定义快慢指针pre和cur,刚开始pre = head ,cur = head.next;
2.pre存放要找值的前一个个节点,cur指向的就是要找的节点,就直接将
找到要删除的节点
pre.next = cur.next;
cur = cur.next;
没找到(都继续往后找)
pre = cur;
cur = cur.next;
3.这里上面我们并没有检查头节点,是从头节点后面节点开始检查的,因此最后要检查一下头节点
如果要删除 head = head.next;


先找要删除节点
找到就将其前一个节点的指向改变在这里插入图片描述
删除后,就继续往后找在这里插入图片描述

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode removeElements(ListNode head, int val) {//判断head是否为nullif(head==null){return null;}ListNode pre = head;ListNode cur = head.next;//从第二个节点开始找while(cur!=null){if(cur.val==val){pre.next = cur.next;//改变指向cur = cur.next;//往后走}else{//没找到就都往后移动pre = cur;cur = cur.next;}}//检查头是否也要删除if(head.val==val){head = head.next;}//最后返回新的头节点return head;}
}

这里其实可以将检查头节点放在最前面
但是为什么我们不这样做呢,因为这样的话,改变了头节点,头节点就变了,有可能下一个节点也是要删除的,这样可能多次改变头节点,可能会比较繁琐,因此把这一步骤放在最后,无论如果只需要判断一次

反转单链表

在这里插入图片描述

目的:将一个链表反转过来
思路:定义一个cur用来指向head.next,头的后面一个,让后面的一个一个链接到前面,直到最后的null,头一直在改变

1.一个cur用来遍历整个链表
2.一个Ncur保存cur的后面链表的首地址,因为每次都会改变cur.next,如果不报保存一下,后面的链表就找不到了
cur = head . next;
while(cur!=null)
{
Ncur = cur.next;//保存后面链表地址
cur.next = head;//修改其指向head
head = cur;//头变成cur
}

在这里插入图片描述
在这里插入图片描述

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseList(ListNode head) {//先判断是否为null或者就一个节点的话直接返回if(head==null){return null;}if(head.next==null){return head;}//先保存一份,删除后就找不到了ListNode cur = head.next;//头变成尾,下面置为nullhead.next=null;while(cur!=null){ListNode Ncur = cur.next;cur.next = head;head = cur;cur = Ncur;}return head;}
}

链表的中间节点

在这里插入图片描述

目的:获取中间节点,如果有两个中间节点,就返回其中第二个节点
思路:使用快慢指针,定义一个fast和slow指针,fast一次走两步,slow一次走已步,同时从head开始,当fast走到链表结束的时候,这时候的slow正好符合我们要找的中间节点的要求
原理:时间一样fast的速度是slow的2倍,fast走完,slow正好走一半
while(fast!=null&&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

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;}//最后返回slow所指向的节点return slow;}
}

返回倒数第K个节点

在这里插入图片描述

目的:找到倒数第K个节点,返回其该节点的值,并且题目已将保证了K是有效的
思路:快慢指针fast和slow从头开始,1.先让fast先走k-1步后2.在让其一起走,最总fast走到末尾就查找结束
原理:找倒数第K个节点,其倒数第K个节点到倒数第一个节点只需要k-1步就可以,相差两个距离
那我们先让fast走k-1步,这样fast就与slow的距离固定为k-1,也就是倒数第K个节距离倒数第一个节点,这时候在让其一起走,直到fast走到最后一个,slow正好是我们要找的节点
同样的速度,同样的时间,固定的距离向后走

在这里插入图片描述
在这里插入图片描述

class Solution {public int kthToLast(ListNode head, int k) {//1.先确定倒数第一个与要查找节点之间间隔//2.将这个间隔为fast和slow之间的间隔//3.如果fast走到最后,slow就是要找的if(head==null){return -1;}ListNode fast = head;ListNode slow = head;int count = 0;//先让fast走k-1步,固定二者之间距离while(count!=k-1){fast = fast.next;count++;}//让后一起向后走//当fast走到倒数第1个,slow正好是倒数第K个,二者间距为k-1while(fast.next!=null){fast = fast.next;slow = slow.next;}//返回节点的值return slow.val;}
}

合并两个有序列表

在这里插入图片描述

目的:将两个非递减顺序的单链表合并为一个新的非递减单链表
思路:1.先定义一个头节点 ,2.遍历两个列表,进行判断,拼接两个列表中val值小的节点,拼接完往后走 3.直到循环到有一个链表结尾了,将另一个列表剩下拼接后面就行了

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {//1.先创建一个节点用来当头//2.比较两个列表数值,进行链接//3.如果出现null就说明有一个结束了,就将另一个链接就行了ListNode Nhead = new ListNode(-1);ListNode tem = Nhead;//用来存放ListNode cur1 = list1;ListNode cur2 = list2;//遍历直到有一个链表到了结束while(cur1!=null&&cur2!=null){if(cur1.val<cur2.val){tem.next = cur1;tem = cur1;cur1 = cur1.next;}else{tem.next = cur2;tem = cur2;cur2 = cur2.next;}}//将另一个为遍历完的进行拼接到后面if(cur1!=null){tem.next = cur1;}if(cur2!=null){tem.next = cur2;}return Nhead.next;}
}

判断链表是否回文

在这里插入图片描述

题目:判断一个链表是否是回文的
思路:我们首先想的就是让其链表前后一起遍历进行比较,但是我们怎么让其后面的向前走呢
1.找到中间节点(fast和slow快慢指针,前面已经讲过了)
2.将中间以后的链表逆置(定义一个cur = slow.next; 从cur开始将节点指向逆向翻转,每次翻转完成slow向后走一步slow=cur,让slow走到尾部)
3.前后分别遍历比较(一个向前一个向后开始进行比较val值是否相同)

>
在这里插入图片描述

public class PalindromeList {public boolean chkPalindrome(ListNode head) {//1.找到中间节点//2.将中间节点后面节点逆置//3.比较if(head==null){return true;}ListNode headA = head;//找中间节点ListNode fast = head;ListNode slow = head;while(fast!=null&&fast.next!=null){fast = fast.next.next;slow = slow.next;}//后面逆置ListNode cur = slow.next;while(cur!=null){ListNode Ncur = cur.next;cur.next  =slow;slow = cur;cur = Ncur;}//比较while(headA!=slow){if(headA.val!=slow.val){return false;}if(headA.next==slow){return true;}headA = headA.next;slow = slow.next;}return true;}
}

相关文章:

  • Linux线程与进程:探秘共享地址空间的并发实现与内
  • Three.js + React 实战系列-3D 个人主页:构建 Hero 场景组件(项目核心)✨
  • 16.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--Github Action
  • 高精度3D圆弧拟合 (C++)
  • 详解 Network.framework:iOS 网络开发的新基石
  • Eclipse Debug 配置指南
  • 苹果(IOS)手机怎么开启开发者模式(简单明了版)
  • 使用 Frida 绕过 iOS 应用程序中的越狱检测
  • 谈谈关于【枚举】类型变量的好处
  • C++?类和对象(下)!!!
  • 从基础到实战的量化交易全流程学习:1.1 量化交易本质与行业生态
  • ultralytics 目标检测 混淆矩阵 背景图像 没被记录
  • 微信小程序,基于uni-app的轮播图制作,轮播图本地文件图片预览
  • 文件操作及读写-爪哇版
  • 关于flink两阶段提交高并发下程序卡住问题
  • 【C++11】Lambda表达式
  • WPF大数据展示与分析性能优化方向及代码示例
  • 导览项目KD-Tree最近地点搜索优化
  • 用高德API提取广州地铁线路(shp、excel)
  • 【优选算法 | 滑动窗口】滑动窗口算法:高效处理子数组和子串问题
  • 国家能源局:支持民营企业参股投资核电项目
  • 中国黄金协会:一季度我国黄金产量同比增1.49%,黄金消费量同比降5.96%
  • 传智教育连续3个交易日跌停:去年净利润由盈转亏
  • 汽车爆炸致俄军中将死亡嫌疑人被羁押,作案全过程披露
  • 点燃“文化活火”,上海百年街区创新讲述“文化三地”故事
  • 广州一季度GDP为7532.51亿元,同比增长3%