力扣链表篇

news/发布时间2024/9/20 7:58:53

以下刷题思路来自代码随想录以及官方题解

文章目录

      • 203.移除链表元素
      • 707.设计链表
      • 206.反转链表
      • 24.两两交换链表中的节点
      • 19.删除链表的倒数第N个节点
      • 面试题 02.07. 链表相交
      • 142.环形链表II

203.移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回新的头节点 。

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]输入:head = [], val = 1
输出:[]输入:head = [7,7,7,7], val = 7
输出:[]
/*** 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) {//首先解决头节点不为空,为val的情况while (head != null && head.val == val) {head = head.next;}// 如果头节点为空if (head == null) {return head;}ListNode pre = head;ListNode cur = head.next;while (cur != null) {// 判断值相等if (cur.val == val) {pre.next = cur.next;} else {pre = cur;}cur = cur.next;}return head;}
}

707.设计链表

你可以选择使用单链表或者双链表,设计并实现自己的链表。

单链表中的节点应该具备两个属性:valnextval 是当前节点的值,next 是指向下一个节点的指针/引用。

如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。

实现 MyLinkedList 类:

MyLinkedList() 初始化 MyLinkedList 对象。
int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。

输入
["MyLinkedList", "addAtHead", "addAtTail", "addAtIndex", "get", "deleteAtIndex", "get"]
[[], [1], [3], [1, 2], [1], [1], [1]]
输出
[null, null, null, null, 2, null, 3]解释
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addAtHead(1);
myLinkedList.addAtTail(3);
myLinkedList.addAtIndex(1, 2);    // 链表变为 1->2->3
myLinkedList.get(1);              // 返回 2
myLinkedList.deleteAtIndex(1);    // 现在,链表变为 1->3
myLinkedList.get(1);              // 返回 3
public class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) {this.val = val;}
}class MyLinkedList {// 存储链表中节点个数int size;// 虚拟头节点ListNode head;public MyLinkedList() {size = 0;head = new ListNode(0);}public int get(int index) {if (index < 0 || index >= size) {return -1;}ListNode cur = head;// 直接遍历到该结点for (int i = 0; i <= index; i++) {cur = cur.next;}return cur.val;}public void addAtHead(int val) {addAtIndex(0, val);}public void addAtTail(int val) {addAtIndex(size, val);}public void addAtIndex(int index, int val) {if (index > size) {return;}if (index < 0) {index = 0;}// 因为需要插入所以size++size++;// 因为是单链表,所以需要找到插入位置的前节点ListNode pre = head;for (int i = 0; i < index; i++) {pre = pre.next;}ListNode newNode = new ListNode(val);// 这里顺序至关重要newNode.next = pre.next;pre.next = newNode;}public void deleteAtIndex(int index) {if (index < 0 || index >= size) {return;}size--;if (index == 0) {head = head.next;return;}ListNode pre = head;for (int i = 0; i < index; i++) {pre = pre.next;}pre.next = pre.next.next;}
}

206.反转链表

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

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
/*** 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) {ListNode preNode = null;ListNode curNode = head;ListNode temp = null;while(curNode != null){//暂存下一个节点temp = curNode.next;//反转箭头curNode.next = preNode;preNode =  curNode;curNode = temp;}return preNode;}
}

24.两两交换链表中的节点

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即只能进行节点交换)。

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

这道题我没看懂,过后再来理解一下。

/*** 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 swapPairs(ListNode head) {if(head == null || head.next == null){return head;}// 获取当前节点的下一个节点ListNode next = head.next;// 进行递归ListNode newNode = swapPairs(next.next);// 这里进行交换next.next = head;head.next = newNode;return next;}
}

19.删除链表的倒数第N个节点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

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

这道题的思路很好理解,点赞!

/*** 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) {// 创建一个虚拟头节点pre,将其next指针指向headListNode pre = new ListNode(0);pre.next = head;// 定义两个指针start和end,都指向preListNode start = pre, end = pre;// 将start指针向前移动n个节点,即start和end之间相隔n个节点while(n != 0) {start = start.next;n--;}// 同时移动start和end指针,直到start指向最后一个节点while(start.next != null) {start = start.next;end = end.next;}// 删除倒数第n个节点,即将end的next指针指向end.next.nextend.next = end.next.next;// 返回删除节点后的链表头节点return pre.next;}
}

下面是力扣官方题解真的通俗移动,膜拜!

class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0, head);int length = getLength(head);ListNode cur = dummy;for (int i = 1; i < length - n + 1; ++i) {cur = cur.next;}cur.next = cur.next.next;ListNode ans = dummy.next;return ans;}public int getLength(ListNode head) {int length = 0;while (head != null) {++length;head = head.next;}return length;}
}

面试题 02.07. 链表相交

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

在这里插入图片描述

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A[4,1,8,4,5],链表 B[5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A[0,9,1,2,4],链表 B[3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A[2,6,4],链表 B[1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null

对于这道题,同样使用哈希表来解决。

/*** 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) {//HashSet是一个没有重复元素的集合Set<ListNode> set = new HashSet<ListNode>();ListNode temp = headA;while(temp != null){set.add(temp);temp = temp.next;}temp = headB;while(temp!=null){if(set.contains(temp)){return temp;}temp = temp.next;}return null;}
}

142.环形链表II

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

我们遍历链表中的每个节点,并将它记录下来;一旦遇到了此前遍历过的节点,就可以判定链表中存在环。借助哈希表可以很方便地实现。

/*** 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) {Set<ListNode> set = new HashSet<>();while (head != null) {if (set.contains(head)) {return head;} else {set.add(head);}head = head.next;}return null;}
}

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

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

相关文章

wcf 简单实践 数据绑定 数据更新ui

1.概要 2.代码 2.1 xaml <Window x:Class"WpfApp3.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expr…

基于x86架构的OpenHarmony应用生态挑战赛等你来战!

为了更快速推进OpenHarmony在PC领域的进一步落地&#xff0c;加快x86架构下基于OpenHarmony的应用生态的繁荣&#xff0c;为北向应用开发者提供一个更加便捷的开发环境&#xff0c;推动OpenHarmony北向应用开发者的增加&#xff0c;助力OpenHarmony在PC领域实现新的突破&#x…

Linux系统Docker部署Nexus Maven并实现远程访问本地管理界面

文章目录 1. Docker安装Nexus2. 本地访问Nexus3. Linux安装Cpolar4. 配置Nexus界面公网地址5. 远程访问 Nexus界面6. 固定Nexus公网地址7. 固定地址访问Nexus Nexus是一个仓库管理工具&#xff0c;用于管理和组织软件构建过程中的依赖项和构件。它与Maven密切相关&#xff0c;可…

Sui在AIBC Eurasia奖项评选中被评为2024年度最佳区块链解决方案

自2023年主网上线以来&#xff0c;经历了爆炸性增长的Layer1区块链Sui在2月25–27日迪拜举办的第二届AIBC Eurasia活动中获得“2024最佳区块链解决方案奖”&#xff08;Best Real World Application Award 2024&#xff09;。这个盛大的活动以世界级的参与者和往届获奖者而闻名…

一篇关于,搬运机器人的介绍

搬运机器人是一种能够自动运输和搬运物品的机器人。它们通常配备有传感器和导航系统&#xff0c;可以在工厂、仓库、医院或其他场所自主移动&#xff0c;并且可以根据预先设定的路径或指令进行操作。 搬运机器人可以用于搬运重物、物料搬运、装卸货物、仓库管理等任务。它们可以…

Python程序的流程

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 年轻是我们唯一拥有权利去编制梦想的时…

springboot227旅游管理系统

springboot旅游管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本旅游管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助使用者在…

《大模型时代-ChatGPT开启通用人工智能浪潮》精华摘抄

原书很长&#xff0c;有19.3w字&#xff0c;本文尝试浓缩一下其中的精华。 知识点 GPT相关 谷歌发布LaMDA、BERT和PaLM-E&#xff0c;PaLM 2 Facebook的母公司Meta推出LLaMA&#xff0c;并在博客上免费公开LLM&#xff1a;OPT-175B。 在GPT中&#xff0c;P代表经过预训练(…

如何运行github上的项目

为了讲明白这个过程&#xff0c;特意做了一个相对来说比较好读懂的原理图&#xff0c;希望和我一样初学的小伙伴也能很快上手哈&#x1f60a; 在Github中找到想要部署的项目&#xff0c;这里以BartoszJarocki/CV&#xff08;线上简历&#x1f4c4;&#xff09;项目为例 先从头…

前端视角对Rust的浅析

概述 本文将从 Rust 的历史&#xff0c;前端的使用场景和业界使用案例一步步带你走进 Rust的世界。并且通过一些简单的例子&#xff0c;了解 Rust 如何应用到前端&#xff0c;提高前端的生产效率。 Rust简史 2006年&#xff0c;软件开发者Graydon Hoare在Mozilla工作期间&#…

C#与VisionPro联合开发——INI存储和CSV存储

1、INI存储 INI 文件是一种简单的文本文件格式&#xff0c;通常用于在 Windows 环境中存储配置数据。INI 文件格式由一系列节&#xff08;section&#xff09;和键值对&#xff08;key-value pairs&#xff09;组成&#xff0c;用于表示应用程序的配置信息。一个典型的 INI 文…

Flink代码单词统计 ---批处理

flatMap&#xff1a;一对多转换操作&#xff0c;输入句子&#xff0c;输出分词后的每个词groupBy&#xff1a;按Key分组&#xff0c;0代表选择第1列作为Keysum&#xff1a;求和&#xff0c;1代表按照第2列进行累加print&#xff1a;打印最终结果 1.WordCount代码编写 需求&am…

k8s资源管理之声明式管理方式

1 声明式管理方式 1.1 声明式管理方式支持的格式 JSON 格式&#xff1a;主要用于 api 接口之间消息的传递 YAML 格式&#xff1a;用于配置和管理&#xff0c;YAML 是一种简洁的非标记性语言&#xff0c;内容格式人性化&#xff0c;较易读 1.2 YAML 语法格式&#xff1a; ●…

C# Onnx 使用onnxruntime部署实时视频帧插值

目录 介绍 效果 模型信息 项目 代码 下载 C# Onnx 使用onnxruntime部署实时视频帧插值 介绍 github地址&#xff1a;https://github.com/google-research/frame-interpolation FILM: Frame Interpolation for Large Motion, In ECCV 2022. The official Tensorflow 2…

五.AV Foundation 视频播放 - 标题和字幕

引言 本篇博客主要介绍使用AV Foundation加载视频资源的时候&#xff0c;如何获取视频标题&#xff0c;获取字幕并让其显示到播放界面。 设置标题 资源标题的元数据内容&#xff0c;我们需要从资源的commonMetadata中获取&#xff0c;在加载AVPlayerItem的时候我们已经指定了…

【Vue】路由

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Vue ⛺️稳中求进&#xff0c;晒太阳 目录 路由 单页应用程序 总结&#xff1a; VueRouter 核心步骤&#xff1a; 组件存放目录的问题 路由的封装 声明式导航 声明式导航 - 导航链…

二叉树(1)

目录 1. 树型结构 1.1 概念 1.2 概念 1.3 树的表示形式 ​编辑 2. 二叉树 2.1 概念 2.2 两种特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储 2.5 二叉树的基本操作 2.5.1 前置说明 2.5.2 二叉树的遍历 1. NLR&#xff1a;前序遍历(亦称先序遍历): 2. LNR&#xff1a;中序遍历…

Unity中URP实现水体(整理优化)

文章目录 前言一、优化水的深度1、我们把 水流动的方向 和 水深浅过渡值&#xff0c;整合到一个四维变量中2、修改 水体流动方向3、在片元着色器中&#xff0c;修改使用过渡变量 二、优化泡沫三、优化水下的扭曲1、修复原本扰动UV的计算 四、优化水面高光1、把高光强度、光滑度…

Leetcoder Day29| 贪心算法part03

1005.K次取反后最大化的数组和 给定一个整数数组 A&#xff0c;我们只能用以下方法修改该数组&#xff1a;我们选择某个索引 i 并将 A[i] 替换为 -A[i]&#xff0c;然后总共重复这个过程 K 次。&#xff08;我们可以多次选择同一个索引 i。&#xff09; 以这种方式修改数组后&a…

基于springboot+vue的街球社区网站(源码+论文)

文章目录 前言 一、功能设计 二、功能实现 系统首页设计 系统前台基本功能设计与实现 ​编辑 系统后台管理功能设计与实现 三、库表设计 四、论文 前言 本文主要讲述了基于SpringBootVue模式的街球社区网站的设计与实现。这里所谓的街球社区网站是通过类似于百度贴吧之类的网上…
推荐文章