代码随想录算法训练营第三天 | 链表理论基础,203.移除链表元素,707.设计链表,206.反转链表

对于链表完全陌生,但是看题目又觉得和数组一样的

链表理论基础 

Q:什么是链表?

A:链表是由一系列结点组成的。每一个结点由两部分组成:数据和指针

203.移除链表元素 

题目:

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

示例 1:

输入:head = [1,2,6,3,4,5,6], val = 6

输出:[1,2,3,4,5]

示例 2:

输入:head = [], val = 1

输出:[]

示例 3:

输入:head = [7,7,7,7], val = 7

输出:[]

思路:

        需要遍历,当元素等于val,指针指向下下个元素的。第一次学习并使用链表,需要熟悉如何建立链表,如何遍历元素。所以一刷基本属于照猫画虎,但是重要的掌握思路,我也不求一遍就通透。

代码:

# Definition for singly-linked list.  定义单链表
# class ListNode:   定义链表的类
#     def __init__(self, val=0, next=None):  
#     链表中的数据和指针,next=None是最后一个结点的属性,即指针指向空\
#     但是在此处,有2种指向:如果有下一个结点,可以再给next赋值,没有就让它默认指向空
#         self.val = val
#         self.next = next
class Solution:def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:# 创建虚拟头部节点,简化删除过程,因为有可能第一个结点就需要删除dummy_head = ListNode(next=head)# 遍历链表,删除val的值cur = dummy_headwhile cur.next:  # 只要当前结点的下一个结点不为空,就循环if cur.next.val == val:cur.next = cur.next.next  # 跳过val值,也就是删除该值的动作else:cur = cur.next  # 如果不等与val,继续遍历return dummy_head.next  # 返回虚拟头节点的指针,也就是去除了val值的新链表

 707.设计链表 

题目:

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

单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,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

思路:

这道题目非常经典,涵盖了链表基本的操作。题目看起来复杂,基本是如下几个问题:

  1. 在头部插入新节点
  2. 在尾部插入新节点
  3. 在中间插入新节点
  4. 删除指定的结点

卡哥强调:需要注意的是新增结点的时候,要让新结点先指向下一个结点,再让上一个结点指向新节点,顺序很重要。

代码:

1、单链表

# 定义一个链表:
class ListNode:def __init__(self, val=0, next=None):self.val = valself.next = nextclass MyLinkedList:  # 单链表# 初始化链表def __init__(self):self.dummy_head = ListNode()  # 建立虚拟节点self.size = 0  # 初始化结点的长度为0,也就是刚开始链表没有任何数字# 获取下标的值def get(self, index: int) -> int:if index < 0 or index >= self.size:  # 在链表之外的范围,不符合return -1cur = self.dummy_head.next  # 必须要用self,for i in range(index):cur = cur.next  # 表示将指针移动到下一个结点return cur.val# 在头部新增一个结点def addAtHead(self, val: int) -> None:self.dummy_head.next =ListNode(val,self.dummy_head.next)  # 虚拟结点指向新节点self.size += 1## 在头部新增一个结点#  加入自己理解写的,看下来和双链表比较接近# def addAtHead(self, val: int) -> None:#     new_node = ListNode(val)  # 创建新节点#     new_node.next = self.dummy_head.next  # 新节点指向头节点#     self.dummy_head.next = new_node  # 虚拟结点指向新节点#     self.size += 1# 在尾部添加一个结点def addAtTail(self, val: int) -> None:# new_node_tail = ListNode(val)cur = self.dummy_head  # 指针当前指向虚拟节点while cur.next:  # 当当前指针没有指向空,则一直循环cur = cur.nextcur.next = ListNode(val)self.size += 1# 在指定下标添加一个结点def addAtIndex(self, index: int, val: int) -> None:if index < 0 or index > self.size:returncur = self.dummy_head# new_node3 = ListNode(val)for i in range(index):cur = cur.nextcur.next = ListNode(val,cur.next)self.size += 1# 删除指定下标的结点def deleteAtIndex(self, index: int) -> None:if index < 0 or index >= self.size:    # 这里的'='非常重要!debug了很久很久……returncur = self.dummy_headfor i in range(index):cur = cur.next   # 在链表中遍历至索引位置的前一个结点cur.next = cur.next.next  # index这个位置的数就等于它的下一个数,就实现了删除index指向的数self.size -= 1# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)class MyLinkedList:

  2、双链表

……暂时还不能完全理解双链表,先把单链表学会了再来……

【总结】

        链表的基本操作和思路已经理解,但是一些临界的条件考虑的还不够周全,甚至写起代码相当生涩。继续加油吧!

 206.反转链表 

题目:

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

示例 1:

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

输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]

输出:[2,1]

示例 3:

输入:head = []

输出:[]

思路:

让每一个结点的指针指向前一个结点。

代码:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:prev=None  # 前一个结点cur=head  # 当前结点next=None  # 下一个结点while cur:next=cur.nextcur.next=prev  # 实现反转prev=curcur=nextreturn prev

今日总结:

        学到新知识的感觉很踏实,但是一次也没有办法消化三道题,对我来说,在学习的过程中手写是很有用的,学习到链表的基础知识并在做题中了解逻辑,明日继续加油!

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

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

相关文章

【电影】【指环王】【中土世界】影碟播放记录

一、写在前面 笔者于5月5日&#xff08;昨天&#xff09;在新加坡淘到了一套《指环王 The Lord of the Rings》DVD光碟&#xff0c;今天却听闻噩耗&#xff0c;Rohan国王Theoden的扮演者&#xff0c;英国演员Bernard Hill去世&#xff08;享年79岁&#xff09;&#xff0c;发文…

从键入网址到网页显示,期间发生了什么?

从键入网址到网页显示&#xff0c;期间发生了什么&#xff1f; 孤单小弟【HTTP】真实地址查询【DNS】指南帮手【协议栈】可靠传输【TCP】远程定位【IP】两点传输【MAC】出口【网卡】送别者【交换机】出境大门【路由器】互相扒皮【服务器与客户端】相关问答 不少小伙伴在面试过程…

一竞技MSI:淘汰赛抽签结果出炉 BLG和T1同半区,TES首轮交手TL!

北京时间5月6日&#xff0c;MSI在今天进入短暂的休赛&#xff0c;在昨天结束的入围赛之后&#xff0c;PSG战队作为外卡赛区唯一的队伍进入到正赛&#xff0c;另外欧洲赛区的FNC战队也是击败GAM战队拿到正赛的资格。在比赛结束之后&#xff0c;也是进行了淘汰赛的胜败分组赛的抽…

GateWay检查接口耗时

添加gateway依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency>创建一个LogTimeGateWayFilterFactory类&#xff0c;可以不是这个名字但是后面必须是x…

关于蓝队应急响应工具箱意见征集

前言 征集一下各位师傅的意见&#xff0c;没用过的师傅可以去以往的文章下载使用&#xff1a; 下载地址&#xff08;有个小小改动&#xff0c;去除了必要的python环境&#xff0c;使其占用空间更小&#xff09;&#xff1a; [护网必备]知攻善防实验室蓝队应急响应工具箱v202…

动态规划算法:路径问题

例题一 解法&#xff08;动态规划&#xff09;&#xff1a; 算法思路&#xff1a; 1. 状态表⽰&#xff1a; 对于这种「路径类」的问题&#xff0c;我们的状态表⽰⼀般有两种形式&#xff1a; i. 从 [i, j] 位置出发&#xff0c;巴拉巴拉&#xff1b; ii. 从起始位置出…

(读书笔记-大模型) LLM Powered Autonomous Agents

目录 智能体系统的概念 规划组件 记忆组件 工具组件 案例研究 智能体系统的概念 在大语言模型&#xff08;LLM&#xff09;赋能的自主智能体系统中&#xff0c;LLM 充当了智能体的大脑&#xff0c;其三个关键组件分别如下&#xff1a; 首先是规划&#xff0c;它又分为以下…

idea无法识别加载pom.xml文件

有时idea无法识别加载pom.xml文件&#xff0c;直接打开pom.xml文件&#xff0c;然后添加到maven就行

创新指南|非凡时代的变革型领导力——五个领导力差异化优势将使高管能够重塑他们的组织

大多数商界领袖现在都明白&#xff0c;我们正在经历一场“伟大的重构”&#xff0c;整个行业、经济和社会都在重塑的时期。然而&#xff0c;考虑到他们面临的短期压力&#xff0c;很少有高管发现自己能够真正应对这些变化&#xff0c;这些变化对他们的组织所需的转型意味着什么…

知识图谱在提升大语言模型性能中的应用:减少幻觉与增强推理的综述

幻觉现象指的是模型在生成文本时可能会产生一些听起来合理但实际上并不准确或相关的输出&#xff0c;这主要是由于模型在训练数据中存在知识盲区所致。 为了解决这一问题&#xff0c;研究人员采取了多种策略&#xff0c;其中包括利用知识图谱作为外部信息源。知识图谱通过将信息…

25.哀家要长脑子了---哈希表

1.525. 连续数组 - 力扣&#xff08;LeetCode&#xff09; 在我对通义千问的一番折磨下&#xff0c;终于弄清楚一点点了。哈希表存储前缀和数组值 用一个counter来记录nums中0、1数量差值的变化。 哈希表map存储某个特定的counter值首次出现的位置。counter的计算&#xff1a;…

[redis] redis为什么快

1. Redis与Memcached的区别 两者都是非关系型内存键值数据库&#xff0c;现在公司一般都是用 Redis 来实现缓存&#xff0c;而且 Redis 自身也越来越强大了&#xff01;Redis 与 Memcached 主要有以下不同&#xff1a; (1) memcached所有的值均是简单的字符串&#xff0c;red…