【力扣hot100】刷题笔记Day10

前言

  • 一鼓作气把链表给刷完!!中等题困难题冲冲冲啊啊啊!

25. K 个一组翻转链表 - 力扣(LeetCode)

  • 模拟

    • class Solution:
          def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
              # 翻转链表前k项
              def reverse(head, k):
                  pre, cur = None, head
                  while cur and k:
                      temp = cur.next
                      cur.next = pre
                      pre = cur
                      cur = temp
                      k -= 1
                  return pre, head  # pre为头,head为尾
              dummy = ListNode(0, head)
              pre = cur = dummy
              count = k  # 用于重复计数
              while cur.next and count:
                  count -= 1
                  cur = cur.next
                  if count == 0:
                      temp = cur.next  # 存一下段后节点
                      pre.next, cur = reverse(pre.next, k)  # 连接段前+翻转
                      cur.next = temp  # 连上段后节点
                      pre = cur  # 更新pre指针
                      count = k  # 恢复count继续遍历
              return dummy.next

 138. 随机链表的复制 - 力扣(LeetCode)

  • 路飞的题解真是太强啦!!优雅清晰简洁
  • 哈希表

    • """
      # Definition for a Node.
      class Node:
          def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
              self.val = int(x)
              self.next = next
              self.random = random
      """
      
      class Solution:
          def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
              if not head: return None
              dic = {}
              # 1. 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射
              cur = head
              while cur:
                  dic[cur] = Node(cur.val)
                  cur = cur.next
              # 2. 构建新节点的 next 和 random 指向
              cur = head
              while cur:
                  dic[cur].next = dic.get(cur.next)
                  dic[cur].random = dic.get(cur.random)
                  cur = cur.next
              # 3. 返回新链表的头节点    
              return dic[head]
  • 拼接 + 拆分

    • class Solution:
          def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
              if not head: return None
              dic = {}
              # 1. 复制各节点,并构建拼接链表
              cur = head
              while cur:
                  temp = Node(cur.val)
                  temp.next = cur.next
                  cur.next = temp
                  cur = temp.next
              # 2. 构建各新节点的 random 指向
              cur = head
              while cur:
                  if cur.random:
                      cur.next.random = cur.random.next
                  cur = cur.next.next
              # 3. 拆分两链表
              cur = newhead = head.next
              pre = head
              while cur.next:
                  pre.next = pre.next.next
                  cur.next = cur.next.next
                  pre = pre.next
                  cur = cur.next
              pre.next = None  # 单独处理原链表尾节点
              return newhead  # 返回新链表头节点

148. 排序链表 - 力扣(LeetCode)

  • 归并排序(顶到底递归)

    • 参考路飞题解
    • class Solution:
          def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
              if not head or not head.next: return head
              # 快慢指针分割链表
              slow, fast = head, head.next
              while fast and fast.next:
                  fast, slow = fast.next.next, slow.next
              mid = slow.next  # 右半部分的头节点
              slow.next = None  # 断开两部分
              # 递归进行归并排序
              left = self.sortList(head)
              right = self.sortList(mid)
              # 合并左右两个链表
              dummy = cur = ListNode(0)
              while left and right:  # 根据大小依次插入新链表
                  if left.val < right.val:
                      cur.next = left
                      left = left.next
                  else:
                      cur.next = right
                      right = right.next
                  cur = cur.next
              cur.next = left if left else right  # 接上剩下的
              return dummy.next
  • 归并排序(底到顶合并) 

    • class Solution:
          def sortList(self, head: ListNode) -> ListNode:
              # 合并两个有序链表
              def merge(head1, head2):
                  dummy = cur = ListNode(0)
                  while head1 and head2:
                      if head1.val < head2.val:
                          cur.next = head1
                          head1 = head1.next
                      else:
                          cur.next = head2
                          head2 = head2.next
                      cur = cur.next
                  cur.next = head1 if head1 else head2
                  return dummy.next
              # 如果只有一个节点直接返回head
              if not head: return head
              # 统计链表长度
              lenth = 0
              cur = head
              while cur:
                  cur = cur.next
                  lenth += 1
              # 开始循环合并
              dummy = ListNode(0, head)
              sublenth = 1
              while sublenth < lenth:
                  pre, cur = dummy, dummy.next
                  while cur:
                      head1 = cur
                      for i in range(1, sublenth):
                          if cur.next:
                              cur = cur.next
                          else:
                              break  # 如果还没找到head2说明不用合并,下一轮
                      head2 = cur.next
                      if not head2: break  # 空就不合并了
                      cur.next = None  # 断开第一段后
                      cur = head2
                      for i in range(1, sublenth):
                          if cur.next:
                              cur = cur.next
                          else:
                              break
                      temp = cur.next  
                      cur.next = None  # 断开第二段后
                      cur = temp
                      merged = merge(head1, head2)  # 合并
                      pre.next = merged
                      while pre.next:
                          pre = pre.next  # pre更新到合并后链表的最后
                      pre.next = temp  # 重新连接第二段后
                  # 下一轮合并
                  sublenth *= 2
              return dummy.next

 23. 合并 K 个升序链表 - 力扣(LeetCode)

  • 依次合并

    • class Solution:
          def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
              # 合并两个有序链表
              def merge(head1, head2):
                  dummy = cur = ListNode(0)
                  while head1 and head2:
                      if head1.val < head2.val:
                          cur.next = head1
                          head1 = head1.next
                      else:
                          cur.next = head2
                          head2 = head2.next
                      cur = cur.next
                  cur.next = head1 if head1 else head2
                  return dummy.next
              lenth = len(lists)
              if lenth == 0:
                  return None
              # 每遍历一个链表就合并掉
              dummyhead = ListNode(0)
              for i in range(0, len(lists)):
                  dummyhead.next = merge(dummyhead.next, lists[i])
              return dummyhead.next
  •  分治合并

    • class Solution:
          def mergeKLists(self, lists: List[ListNode]) -> ListNode:
              # 如果输入为空,直接返回空
              if not lists:
                  return 
              # 获取链表列表的长度
              n = len(lists)
              # 调用递归函数进行合并
              return self.merge(lists, 0, n-1)
          
          def merge(self, lists, left, right):
              # 当左右指针相等时,表示只有一个链表,直接返回该链表
              if left == right:
                  return lists[left]
              # 计算中间位置
              mid = left + (right - left) // 2
              # 递归地合并左半部分和右半部分的链表
              l1 = self.merge(lists, left, mid)
              l2 = self.merge(lists, mid+1, right)
              # 调用合并两个有序链表的函数
              return self.mergeTwoLists(l1, l2)
          
          def mergeTwoLists(self, l1, l2):
              # 若其中一个链表为空,则直接返回另一个链表
              if not l1:
                  return l2
              if not l2:
                  return l1
              # 比较两个链表头结点的大小,选择较小的作为新链表的头结点
              if l1.val < l2.val:
                  l1.next = self.mergeTwoLists(l1.next, l2)
                  return l1
              else:
                  l2.next = self.mergeTwoLists(l1, l2.next)
                  return l2
  •  最小堆

    • """
      假设有3个有序链表分别是:1->4->5, 1->3->4, 2->6。
      初始时,最小堆为空。我们依次将(1,0),(1,1),(2,2)加入最小堆。
      然后不断弹出最小值(1,0),(1,1),(2,2),加入到结果链表中,
      并将对应链表的下一个节点值和索引加入最小堆,直到最小堆为空。
      最终得到的合并后的链表为1->1->2->3->4->4->5->6
      """
      class Solution:
          def mergeKLists(self, lists: List[ListNode]) -> ListNode:
              import heapq
              # 创建虚拟节点
              dummy = ListNode(0)
              p = dummy
              head = []
              # 遍历链表数组
              for i in range(len(lists)):
                  if lists[i] :
                      # 将每个链表的头结点值和索引加入到最小堆中
                      heapq.heappush(head, (lists[i].val, i))
                      lists[i] = lists[i].next
              while head:
                  # 弹出最小堆中的值和对应的索引
                  val, idx = heapq.heappop(head)
                  # 创建新节点并连接到结果链表上
                  p.next = ListNode(val)
                  p = p.next
                  # 如果该链表还有剩余节点,则将下一个节点的值和索引加入到最小堆中
                  if lists[idx]:
                      heapq.heappush(head, (lists[idx].val, idx))
                      lists[idx] = lists[idx].next
              # 返回合并后的链表
              return dummy.next

146. LRU 缓存 - 力扣(LeetCode)

  • 哈希 + 双向链表

    • 借用灵神题解的图,really good
    • class Node:
          # 提高访问属性的速度,并节省内存
          __slots__ = 'prev', 'next', 'key', 'value'
          def __init__(self, key=0, value=0):
              # self.prev = None
              # self.next = None
              self.key = key
              self.value = value
      
      class LRUCache:
          def __init__(self, capacity: int):
              self.capacity = capacity
              self.dummy = Node()  # 哨兵节点
              self.dummy.prev = self.dummy
              self.dummy.next = self.dummy
              self.key_to_node = dict()
      
          def get_node(self, key: int) -> Optional[Node]:
              if key not in self.key_to_node:  # 没有这本书
                  return None
              node = self.key_to_node[key]  # 有这本书
              self.remove(node)  # 把这本书抽出来
              self.push_front(node)  # 放在最上面
              return node
      
          def get(self, key: int) -> int:
              node = self.get_node(key)
              return node.value if node else -1
      
          def put(self, key: int, value: int) -> None:
              node = self.get_node(key)
              if node:  # 有这本书
                  node.value = value  # 更新 value
                  return
              self.key_to_node[key] = node = Node(key, value)  # 新书
              self.push_front(node)  # 放在最上面
              if len(self.key_to_node) > self.capacity:  # 书太多了
                  back_node = self.dummy.prev
                  del self.key_to_node[back_node.key]
                  self.remove(back_node)  # 去掉最后一本书
      
          # 删除一个节点(抽出一本书)
          def remove(self, x: Node) -> None:
              x.prev.next = x.next
              x.next.prev = x.prev
      
          # 在链表头添加一个节点(把一本书放在最上面)
          def push_front(self, x: Node) -> None:
              x.prev = self.dummy
              x.next = self.dummy.next
              x.prev.next = x
              x.next.prev = x
      
      # Your LRUCache object will be instantiated and called as such:
      # obj = LRUCache(capacity)
      # param_1 = obj.get(key)
      # obj.put(key,value)

后言

  • 链表终于结束了!后面这几道真是难到我了,基本都是CV写出来的,还是得多沉淀啊 !休息一下,晚上干点活了,不然新学期要被老板骂骂

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

having子句

目录 having子句 having和where的区别 Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 现在要求查询出每个职位的名称&#xff0c;职位的平均工资&#xff0c;但是要求显示平均工资高于 200 的职位 按照职位先进行分组&#xff0c;同…

四问带你搞懂 I3C

大家都知道 I2C &#xff0c;它的全称是 Inter Integrated Circuit &#xff0c;那 I3C 又是什么&#xff1f; I3C 是 MIPI &#xff08;Mobile Industry Processor Interface&#xff09;移动产业处理器接口联盟推出的&#xff0c;全称是 Improved Inter Integrated Circuit &…

玩转网络抓包利器:Wireshark常用协议分析讲解

Wireshark是一个开源的网络协议分析工具&#xff0c;它能够捕获和分析网络数据包&#xff0c;并以用户友好的方式呈现这些数据包的内容。Wireshark 被广泛应用于网络故障排查、安全审计、教育及软件开发等领域。关于该工具的安装请参考之前的文章&#xff1a;地址 &#xff0c;…

【动态规划专栏】专题四:子数组问题--------最大子数组和环形子数组的最大和

本专栏内容为&#xff1a;算法学习专栏&#xff0c;分为优选算法专栏&#xff0c;贪心算法专栏&#xff0c;动态规划专栏以及递归&#xff0c;搜索与回溯算法专栏四部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn个人主页&#xff1a;小…

openEuler2203 LTS安装VMware WorkStation Pro 17并远程桌面连接Linux服务器

openEuler 2203 LTS默认只有命令行&#xff0c;没有GUI图形界面&#xff0c;在其中安装VMware WorkStation需要有图形界面的支持。这里以安装深度的DDE桌面环境&#xff0c;最后通过VNC远程桌面连接Linux服务器操作VMware WorkStation。 以下操作请保持网络能正常连接 1、安装…

【网站项目】679学生学籍管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

gitlab的使用

前一篇文章我们已经知道Git人人都是中心&#xff0c;那他们怎么交互数据呢&#xff1f; • 使用GitHub或者码云等公共代码仓库 • 使用GitLab私有仓库 目录 一、安装配置gitlab 安装 初始化 这里初始化完成以后需要记住一个初始密码 查看状态 二、使用浏览器访问&#xf…

瑞_VMware虚拟机安装Linux纯净版(含卸载,图文超详细)

文章目录 1 资源准备1.1 官方资源1.2 帮助资源 2 安装 VMware3 安装 CentOS 73.1 镜像 附&#xff1a;VMware删除已安装的操作系统 &#x1f64a; 前言&#xff1a;VMware虚拟机安装Linux纯净版 VMware版本&#xff1a;VMware Workstation 16.2.4Linux版本&#xff1a;CentOS 7…

Stable Diffusion 模型分享:A-Zovya RPG Artist Tools(RPG 大师工具箱)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 A-Zovya RPG Artist Tools 模型是一个针对 RPG 训练的一个模型&#xff0c;可以生成一些 R…

如何使用eXtplorer部署个人云存储空间并实现公网访问内网数据

文章目录 1. 前言2. eXtplorer网站搭建2.1 eXtplorer下载和安装2.2 eXtplorer网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1. 前言 通过互联网传输文件&#xff0c;是互联网最重要的应用之一&#xff0c;无论是…

内衣洗衣机哪个好用?顶流爆款内衣洗衣机推荐

大家都知道&#xff0c;内衣裤一天不洗&#xff0c;就会滋生很多细菌&#xff0c;很多女生既要忙工作又要忙家务&#xff0c;衣服总会积攒到一堆再去清洗&#xff0c;在潮湿的天气&#xff0c;这样甚至会有发霉的情况出现&#xff0c;而传统的用手洗贴身衣物&#xff0c;看起来…

冷链物流追踪:Java与MySQL的协同实践

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Unity NavMesh 清除不可行走区域

通常场景中物体设置为static或Navigation Static后&#xff0c;打开Navigation使用默认设置烘焙NavMesh&#xff0c;模型顶部和底部会出现蓝色网格&#xff0c;但其中有部分属于不可能到达区域&#xff0c;如下图 本文介绍两种可去掉NavMesh中不需要网格的方法&#xff1a; 方…

无痛法门,助力学习

**注&#xff1a;**本文摘自一位网友“我就是贺生啊”&#xff0c;博主觉得很有道理&#xff0c;便想记录下来分享给大家。仅个人想法&#xff0c;谨慎参考&#xff0c;也欢迎大家说出自己的想法。 引言 在我们学习新知识的时候&#xff0c;会觉得很痛苦&#xff0c;制定学习…

软件设计不是CRUD(12):低耦合模块设计理论——业务抽象:模块分层操作

接上文《软件设计不是CRUD(11):低耦合模块设计理论——业务抽象:规划模块分层》 3、模块的边界 上篇文章的内容基本上说清楚了模块为什么要进行分层设计,以及模块分层设计所遵循的基本原则。本节内容我们就来讨论一下如何实际进行模块的分层规划。前文已经提到,在完成从…

机器人内部传感器阅读笔记及心得-位置传感器-电位器式位置传感器

位置传感器 位置感觉是机器人最基本的感觉要求&#xff0c;可以通过多种传感器来实现。位置传感器包括位置和角度检测传感器。常用的机器人位置传感器有电位器式、光电式、电感式、电容式、霍尔元件式、磁栅式及机械式位置传感器等。机器人各关节和连杆的运动定位精度要求、重…

数字之美:探索人工智能绘画的奇妙世界

目录 引言AI绘画的定义与发展历程定义与发展历程AI绘画产品有哪些? AI绘画的应用领域设计与创意产业影视与游戏制作数字艺术与展览 AI绘画的基本原理与技术深度学习与神经网络生成对抗网络&#xff08;GAN&#xff09;风格迁移算法 AI绘画效果展示一只带着墨镜的小猫在高楼林立…

尾矿库排洪系统结构仿真软件WKStruc(可试用)

1、背景介绍 尾矿库作为重大危险源之一&#xff0c;在国际灾害事故排名中位列第18位&#xff0c;根据中国钼业2019年8月刊《中国尾矿库溃坝与泄漏事故统计及成因分析》的统计&#xff0c;在46起尾矿库泄漏事故中&#xff0c;由于排洪设施导致的尾矿泄漏事故占比高达1/3&#x…

手机连接电脑后资源管理器无法识别(识别设备但无法访问文件)

问题描述 小米8刷了pixel experience系统,今天用电脑连接后无法访问手机文件,但是手机选择了usb传输模式为文件传输 解决办法 在设备和打印机页面中右键选择属性 点击改变设置 卸载驱动,注意勾选删除设备的驱动程序软件 卸载后重新连接手机,电脑弹出希望对设备进行什么操作时…

家庭能耗监控系统

随着能源成本的不断上升和环保意识的增强&#xff0c;家庭能耗监控系统变得越来越重要。这种系统是智能家居技术的一部分&#xff0c;它使得家庭用户能够实时监视和管理其能源使用情况&#xff0c;从而达到节能减排的目的。 一、系统组成 家庭能耗监控系统通常由传感器、智能计…