秋招力扣Hot100刷题总结——链表

1. 反转链表题目连接

  • 题目要求:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
    在这里插入图片描述
  • 代码及思路
    • 遍历所有节点,将所有节点的next指向前一个节点
    • 由于要改变节点的next指向,而链表是单向的,因此需要使用一个节点变量先保存当前节点的next节点,然后再指向前一个节点
    • 代码
class Solution {public ListNode reverseList(ListNode head) {if(head==null||head.next==null)return head;ListNode pre=null;ListNode cur=head;while(head!=null){cur=head.next;head.next=pre;pre=head;head=cur;}return pre;}
}

2. LRU 缓存(高频) 题目链接

  • 题目要求:请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
    实现 LRUCache 类:
    LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
    int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
    void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
    函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
    在这里插入图片描述
  • 代码及思路
    • 使用双向链表进行实现,便于调整节点的位置
    • 需要注意的是还需要一个hashmap来存储关键字和节点的对应的关系,并且在相应的操作时不要忘记修改hashmap
    • 代码
class LRUCache {class DNode{int val;int key;DNode next;DNode pre;public DNode(){ }public DNode(int val,int key){this.val=val;this.key=key;}}DNode head;DNode tail;int size;int capacity;Map<Integer,DNode> cache=new HashMap<>();public LRUCache(int capacity) {head=new DNode();tail=new DNode();head.next=tail;tail.pre=head;this.capacity=capacity;size=0;}public int get(int key) {if(cache.containsKey(key)){DNode node=cache.get(key);moveToHead(node);return node.val;}return -1;}public void put(int key, int value) {if(cache.containsKey(key)){DNode node=cache.get(key);node.val=value;moveToHead(node);}else{DNode node=new DNode(value,key);cache.put(key,node);insertHead(node);size++;if(size>capacity){int lastKey=moveTail();cache.remove(lastKey);size--;}}}private void insertHead(DNode node){node.next=head.next;head.next.pre=node;head.next=node;node.pre=head;}private void moveToHead(DNode node){node.pre.next=node.next;node.next.pre=node.pre;insertHead(node);}private int moveTail(){int key=tail.pre.key;tail.pre=tail.pre.pre;tail.pre.next=tail;return key;}
}/*** Your LRUCache object will be instantiated and called as such:* LRUCache obj = new LRUCache(capacity);* int param_1 = obj.get(key);* obj.put(key,value);*/

3.合并两个有序链表 题目链接

  • 题目要求:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
    在这里插入图片描述
  • 代码及思路
    • 先遍历两个链表,选择值小的节点加入合并后的链表
    • 当其中一个链表为空时结束循环,将不为空的链表剩下节点整个加入合并后的链表
    • 最好使用一个虚拟头接点,便于处理
    • 代码
/*** 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 mergeTwoLists(ListNode list1, ListNode list2) {ListNode dumpy=new ListNode();ListNode cur=dumpy;while(list1!=null&&list2!=null){if(list1.val<=list2.val){cur.next=list1;list1=list1.next;}else{cur.next=list2;list2=list2.next;}cur=cur.next;}cur.next=list1==null?list2:list1;return dumpy.next;}
}

4. 环形链表 题目链接

  • 题目要求:给你一个链表的头节点 head ,判断链表中是否有环。
    如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
    如果链表中存在环 ,则返回 true 。 否则,返回 false 。
    在这里插入图片描述
  • 代码及思路
    • 使用快慢指针解决问题,慢指针每次移动一步,快指针每次移动两步(相遇问题)
    • 当快慢指针相遇表明存在环
    • 代码
public class Solution {public boolean hasCycle(ListNode head) {ListNode slow=head;ListNode fast=head;while(fast!=null&&fast.next!=null){slow=slow.next;fast=fast.next.next;if(slow==fast)return true;}return false;}
}

5.环形链表 II 题目链接

  • 题目要求:给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
    如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
    不允许修改 链表。
    在这里插入图片描述
  • 代码及思路
    • 本题是在找链表是否为环的基础上找出环的入口点
    • 在找环的过程中,当快慢指针相遇时慢指针从头开始,然后快指针和慢指针每次相同速度移动,下一次相遇的节点即为环入口(具体分析需要数学)
    • 代码
/*** Definition for singly-linked list.* class ListNode {*     int val;*     ListNode next;*     ListNode(int x) {*         val = x;*         next = null;*     }* }*/
public class Solution {public ListNode detectCycle(ListNode head) {ListNode slow=head;ListNode fast=head;while(fast!=null&&fast.next!=null){slow=slow.next;fast=fast.next.next;if(slow==fast){slow=head;while(slow!=null){if(slow==fast)return slow;slow=slow.next;fast=fast.next;}}}return null;}
}

6. 合并 K 个升序链表 题目链接

  • 题目要求:给你一个链表数组,每个链表都已经按升序排列。
    请你将所有链表合并到一个升序链表中,返回合并后的链表。
    在这里插入图片描述
  • 代码及思路
    • 采用逐个合并的方法,每次合并当前链表前已经合并的链表和当前链表
    • 代码
class Solution {public ListNode mergeKLists(ListNode[] lists) {if(lists.length==0)return null;if(lists.length==1)return lists[0];ListNode newHead=new ListNode();newHead.next=mergeTwo(lists[0],lists[1]);for(int i=2;i<lists.length;i++){newHead.next=mergeTwo(newHead.next,lists[i]);}return newHead.next;}private ListNode mergeTwo(ListNode l1,ListNode l2){ListNode dumpy=new ListNode();ListNode cur=dumpy;while(l1!=null&&l2!=null){if(l1.val<=l2.val){cur.next=l1;l1=l1.next;}else{cur.next=l2;l2=l2.next;}cur=cur.next;}cur.next=l1!=null?l1:l2;return dumpy.next;}
}

7.相交链表 题目链接

  • 题目要求:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
    图示两个链表在节点 c1 开始相交:
    在这里插入图片描述
  • 代码及思路
    • 计算两个链表的长度,让较长的链表先走 (lengthA - lengthB) 步,这样两个链表就从同一节点开始遍历
    • 然后同时遍历两个链表,找到第一个相同的节点,即为相交节点
    • 代码
/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) {*         val = x;*         next = null;*     }* }*/
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode curA=headA;ListNode curB=headB;int l1=0;int l2=0;while(curA!=null){l1++;curA=curA.next;}while(curB!=null){l2++;curB=curB.next;}int move=Math.abs(l1-l2);curA=l1>l2?headA:headB;curB=l1>l2?headB:headA;while(move-->0){curA=curA.next;}while(curA!=null&&curB!=null){if(curA==curB)return curA;curA=curA.next;curB=curB.next;}return null;}
}

8. 删除链表的倒数第 N 个结点 题目链接

  • 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
    在这里插入图片描述
  • 代码及思路
    • 使用快慢指针,快指针先移动n次
    • 然后快慢指针以相同速度每次移动一个节点一起移动,当快指针到达最后一个节点时,慢指针的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 removeNthFromEnd(ListNode head, int n) {ListNode dumpy=new ListNode();dumpy.next=head;ListNode slow=dumpy;ListNode fast=dumpy;while(n-->0){fast=fast.next;}while(fast.next!=null){slow=slow.next;fast=fast.next;}slow.next=slow.next.next;return dumpy.next;}
}

9. 排序链表 题目链接

  • 题目要求:给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
    在这里插入图片描述
  • 代码及思路
    • 使用快排的思想,每次每次找到链表的中间节点,然后将链表分成两个子链表进行排序
    • 然后将两个排序后的子链表合并成一个链表(之前已经做过)
    • 代码
class Solution {public ListNode sortList(ListNode head) {if(head==null||head.next==null)return head;ListNode mid=findMid(head);ListNode rightHead=mid.next;mid.next=null;ListNode n1=sortList(head);ListNode n2=sortList(rightHead);return mergr(n1,n2);}private ListNode findMid(ListNode head){if(head==null||head.next==null){return head;}ListNode slow=head;ListNode fast=head.next.next;while(fast!=null&&fast.next!=null){slow=slow.next;fast=fast.next.next;}return slow;}private ListNode mergr(ListNode n1,ListNode n2){ListNode dumpy=new ListNode();ListNode cur=dumpy;while(n1!=null&&n2!=null){if(n1.val<=n2.val){cur.next=n1;n1=n1.next;}else{cur.next=n2;n2=n2.next;}cur=cur.next;}cur.next=n1!=null?n1:n2;return dumpy.next;}
}

10. 两数相加 题目链接

  • 题目要求:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
    请你将两个数相加,并以相同形式返回一个表示和的链表。
    你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
    在这里插入图片描述
  • 代码及思路
    • 遍历两个链表,每一次分别使用两个整数取出两个链表中节点值
    • 如果链表节点为空,则该整数值为0即可
    • 每次相加之后注意需要进位,因此当前结果值应该是两个链表节点值和上一节点和的进位之和与10取余
    • 最后注意两个链表都为空后还要看最后有没有进位
    • 代码
class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {int c=0;ListNode dumpy=new ListNode();ListNode cur=dumpy;while(l1!=null||l2!=null){int a=0;int b=0;if(l1!=null){a=l1.val;l1=l1.next;}if(l2!=null){b=l2.val;l2=l2.next;}int num=(a+b+c)%10;c=(a+b+c)/10;ListNode node=new ListNode(num);cur.next=node;cur=cur.next;}if(c!=0){cur.next=new ListNode(c);}return dumpy.next;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/52200.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Mac】植物大战僵尸杂交版 for Mac(经典策略塔防游戏)游戏介绍

游戏介绍 植物大战僵尸杂交版 for Mac是一款非常受欢迎的策略塔防游戏&#xff0c;植物大战僵尸游戏以其独特的主题、幽默的风格和富有挑战性的关卡设计而著称。玩家需要种植各种植物来防御入侵的僵尸&#xff0c;每种植物都有其特定的功能和攻击方式。植物大战僵尸杂交版&…

Android 上下滑隐藏显示状态栏

一、DisplayPolicy类中监听滑动事件&#xff0c;然后发送广播事件 Android12类路径&#xff1a; frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.javamSystemGestures new SystemGesturesPointerEventListener(mUiContext, mHandler,new SystemGest…

SQL注入(head、报错、盲注)

目录 【学习目标、重难点知识】 【学习目标】 【重难点知识】 1. 报错注入 1.1 那么什么是报错注入呢&#xff1f; 1.2 报错注入原理 extractvalue函数 updatexml函数 1.3 靶场解析 靶场练习 2. HEAD注入 2.1 相关全局变量 2.2 靶场解析 burp暴力破解 靶场练习 3…

java常见面试题汇总

&#x1f30f;个人博客主页&#xff1a;意疏-CSDN博客 希望文章能够给到初学的你一些启发&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏支持一下笔者吧&#xff5e; 阅读指南&#xff1a; 开篇说明一、封装 继承 多态1.封装2.继承3.多态 二、什么是重载…

初始化列表 / 隐式转换 / 静态

目录 初始化列表隐式转换单参数的隐式类型转换多参数的隐式类型转换explicit关键字 static 初始化列表 大部分时候成员变量在对象实例化的时候调用构造函数就整体定义了&#xff0c;注意此时只有定义&#xff0c;不算初始化。而定义后的值的值是在构造函数里面给的。我们知道构…

<数据集>无人机航拍不同高度牧羊识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;6065张 标注数量(xml文件个数)&#xff1a;6065 标注数量(txt文件个数)&#xff1a;6065 标注类别数&#xff1a;1 标注类别名称&#xff1a;[sheep] 序号类别名称图片数框数1sheep6065149785 使用标注工具&…

Macos M1 IDEA本地调试 HBase 2.2.2

# 1. 前提 执行 mvn clean package assembly:single -DskipTests没问题&#xff0c;并在hbase-assembly/target目录下生成hbase-2.2.2-bin.tar.gz 文件夹 证明Maven 下载依赖没问题 1.1 报错 1 这里应该是报错找不到 com.google.protobuf:protoc:exe:osx-aarch_64:3.5.1 …

入门STM32—外部中断

外部中断的存在使得微控制器能够及时响应外部事件&#xff0c;避免频繁的轮询操作&#xff0c;从而提高系统的实时性、效率和低功耗性能。 1.什么是外部中断&#xff1f; 外部中断是指微控制器接收到外部引脚的信号变化时触发的中断。STM32F103系列微控制器支持多个外部中断线…

鸿蒙(API 12 Beta3版)【DRM会话管理(C/C++)】数字版权保护开发

DRM会话管理&#xff08;MediaKeySession&#xff09;支持媒体密钥管理及媒体解密等&#xff0c;MediaKeySession实例由系统管理里的MediaKeySystem实例创建和销毁。 开发步骤 导入NDK接口&#xff0c;接口中提供了DRM相关的属性和方法&#xff0c;导入方法如下。 #include &…

学习嵌入式第二十九天

ipc进程间通信方式 PC&#xff0c;即进程间通信&#xff08;Inter-Process Communication&#xff09;&#xff0c;是操作系统中不同进程之间交换数据的一种机制。以下是一些常见的IPC方式&#xff1a; 管道&#xff1a;用于父子进程或兄弟进程之间的通信。消息队列&#xff…

selenium-java实现自动登录跳转页面

如果要一直刷新一个网页&#xff0c;总不能人工一直去点&#xff0c;所以想到大学时候学过selenium技术&#xff0c;写个脚本来一直刷新&#xff0c;因为经常写java语言&#xff0c;所以选用java语言来写 实验环境 注意&#xff0c;需要先准备好Google浏览器和Chrome-Driver驱…

ffmpeg6.1集成Plus-OpenGL-Patch滤镜

可参考上一篇文章。ffmpeg6.1集成ffmpeg-gl-transition滤镜-CSDN博客 安装思路大致相同&#xff0c; 因为 Plus-OpenGL-Patch也是基于 ffmpeg 4.x 进行开发的&#xff0c;所以在高版本上安装会有很多报错。 这是我安装后的示例&#xff0c;需要安装教程或者改代码可私信我。 …

记录一次 Redis 优化发送数据(使用管道批量传送)

一 项目背景 此前的项目中&#xff0c;鉴于客户方服务器的安全配置对 MQ 中间件有所限制&#xff0c;我们只得采用 Redis 的 list 作为简易的 MQ 来传送报文数据。然而&#xff0c;近段时间客户关闭了相关端口&#xff0c;导致大量数据积压&#xff0c;需要进行补发。在补发过程…

大数据背景下基于Python的牛油果销售数据可视化分析

注&#xff1a;源码在最后&#xff0c;只是一次实验记录&#xff0c;不合理的地方自行修改。 一 研究背景及意义 21世纪以来&#xff0c;随着科学技术的进步&#xff0c;人们的生活水平也随之大幅提升提高。在科技和经济快速发展下&#xff0c;全球已经进入了大数据时代。大数…

8.21-部署eleme项目

1.设置主从从mysql57服务器 &#xff08;1&#xff09;配置主数据库 [rootmsater_5 ~]# systemctl stop firewalld[rootmsater_5 ~]# setenforce 0[rootmsater_5 ~]# systemctl disable firewalldRemoved symlink /etc/systemd/system/multi-user.target.wants/firewalld.serv…

使用 Fyne 构建 GUI 应用:设置标签文本和自增计数器

引言 Fyne 是一个用 Go 语言编写的跨平台 GUI 框架&#xff0c;它提供了一套丰富的组件来帮助开发者快速构建出漂亮的用户界面。在本文中&#xff0c;我们将通过一个简单的案例来演示如何使用 Fyne 创建 GUI 应用程序&#xff0c;该程序包含设置标签文本和自增计数器的功能。 …

「字符串」前缀函数|KMP匹配:规范化next数组 / LeetCode 28(C++)

目录 概述 思路 核心概念&#xff1a;前缀函数 1.前缀函数 2.next数组 1.考研版本 2.竞赛版本 算法过程 构建next数组 匹配过程 复杂度 Code 概述 为什么大家总觉得KMP难&#xff1f;难的根本就不是这个算法本身。 在互联网上你可以见到八十种KMP算法的next数组…

项目1 物流仓库管理系统

一、项目概述 本项目旨在开发一个功能全面的物流仓库管理系统&#xff0c;以数字化手段优化仓库作业流程&#xff0c;提高管理效率。系统集成了前端用户交互界面与后端数据处理逻辑&#xff0c;涵盖了从用户注册登录、订单管理、货单跟踪到用户信息维护等多个核心业务模块。通…

基于django的学生作业提交与管理系统,有管理后台,可作为课设使用

在本项目中&#xff0c;我们设计并实现了一个基于Django框架的学生作业提交与管理系统&#xff0c;旨在为教师和学生提供一个高效、便捷的作业管理平台。Django作为一个高效的Web框架&#xff0c;因其强大的功能和灵活的架构&#xff0c;使得本系统能够快速开发并扩展。 系统功…

Maven的简单使用

Maven使用 Maven的作用1. 自动构建标准化的java项目结构(1) 项目结构① 约定目录结构的意义② 约定大于配置 (2)项目创建坐标坐标的命名方法&#xff08;约定&#xff09; 2. 帮助管理java中jar包的依赖(1) 配置使用依赖引入属性配置 (2) maven指令(3) 依赖的范围(4) 依赖传递(…