day04 两两交换链表中的节点、删除链表倒数第N个节点、链表相交、环形链表II

题目链接:leetcode24-两两交换链表中的节点, leetcode19-删除链表倒数第N个节点, leetcode160-链表相交, leetcode142-环形链表II

两两交换链表中的节点

基础题没有什么技巧

解题思路见代码注释
时间复杂度: O(n)
空间复杂度: O(1)

Go

func swapPairs(head *ListNode) *ListNode {
	if head == nil || head.Next == nil {
		return head
	}

	virtualHead := &ListNode{Next: head}

	// 指针
	preNode, curNode := virtualHead, head
	var curNodeNext *ListNode

	for curNode != nil && curNode.Next != nil {
		curNodeNext = curNode.Next

		// 初始:cur指向1,curNext指向2
		// prevNode ---> 1----> 2 -------> 3
		//               cur   curNext
		// curNode与curNodeNext进行节点交换

		// prevNode ---> 1    2 -------> 3
		//               |_______________^
		//              cur   curNext
		curNode.Next = curNodeNext.Next

		//                _______
		//               V      |
		// prevNode ---> 1      2        3
		//               |_______________^
		//              cur    curNext
		curNodeNext.Next = curNode

		// prevNode ---> 2 -----> 1 -----> 3
		//              curNext  cur
		preNode.Next = curNodeNext

		// 指针移动
		// 2 -----> 1 -----> 3
		//          preNode  cur
		preNode = curNode
		curNode = curNode.Next

	}
	return virtualHead.Next
}

删除链表倒数第N个节点

思路

节点数范围:1 <= sz <= 30
n范围: 1 <= n <= sz (即n一定时小于节点的数量)
思路:使用快慢指针,slow, fast

  1. 创建一个dummy head
  2. 从dummy开始, 初始slow,fast都指向dummy, fast先移动n个节点
  3. slow和fast同时移动,当fast.Next==nil时,slow所处位置即为倒数第n个节点的前一个节点

example:

dummyH ---> 1 ----> 2 ----> 3 ---> 4

假如n=2, 则要删除倒数第2个节点,即节点3

	初始s和f都指向dummyH:
		dummyH ---> 1 ----> 2 ----> 3 ---> 4
		s  f
	f先移动n个节点:
		dummyH ---> 1 ----> 2 ----> 3 ---> 4
		 s                  f
	s和f同时移动:
	dummyH ---> 1 ----> 2 ----> 3 ---> 4
			            s              f

即当f.Next == nil时,s刚好处于倒数第n个节点的前一个节点,此时只需要执行s.Next = s.Next.Next,就删除了目标节点

时间复杂度: O(n)
空间复杂度: O(1)

Go

func removeNthFromEnd(head *ListNode, n int) *ListNode {
   if head == nil {
   	return head
   }

   dummyH := &ListNode{Next: head}

   s, f := dummyH, dummyH

   // f先移动n个节点
   for i := 0; i < n; i++ {
   	f = f.Next
   }

   for f.Next != nil {
   	s = s.Next
   	f = f.Next
   }

   // 此时s所处的位置为倒数第n个节点的前一个节点
   s.Next = s.Next.Next
   return dummyH.Next
}

链表相交

思路

方法1:
 使用map将A链表节点存储,遍历B链表时判断当前节点是否已经在map中存在,如果存在当前节点就是相交节点.
 此方法时间复杂度O(m+n),m和n分别是链表A,B的长度, 空间复杂度O(m)
方法2:
 将A B补成等长的链表,如下:
 A: a1—>a2—>c1—>c2—>c3—>b1—>b2—>b3—>c1—>c2—>c3
 B: b1—>b2—>b3—>c1—>c2—>c3—>a1—>a2—>c1—>c2—>c3
可以看到,是在c1处相交
 原理:
  假设A链表中,不相交的节点数量有a,相交的节点数量有c,总长度为a+c
  假设B链表中,不相交的节点数量有b,相交的节点数量有c,总长度为b+c
  使用pa, pb两指针同时遍历A链表和B链表
  假如a==b, 遍历链表的两指针会同时到达相交的节点
  假如a!=b,pa遍历A链表之后遍历B链表,pb遍历B链表之后遍历A链表
   此时对于A链表来说总长度为: (a+c) + (b+c) —> (a+c+b) + c
   对于B链表来说总长度为: (b+c) + (a+c) —> (b+c+a) + c
   即,pa和pb都遍历了(a+b+c)个节点然后同时到达了相交的节点

时间复杂度O(m+n),m和n分别是链表A,B的长度
空间复杂度O(1)

Go

func getIntersectionNode(headA, headB *ListNode) *ListNode {
	// 两个链表都不为nil时才会相交
	if headA == nil || headB == nil {
		return nil
	}

	pa, pb := headA, headB

	// 如果A和B没有相交的点,最终pa和pb都会为nil, 然后退出
	for pa != pb {
		if pa == nil {
			// A已经遍历完,开始遍历B
			pa = headB
		} else {
			pa = pa.Next
		}

		if pb == nil {
			// B已经遍历完开始遍历A
			pb = headA
		} else {
			pb = pb.Next
		}
	}

	return pa
}

环形链表II

思路

  1. 判断链表是否有环
  2. 找出环的入口(返回入口节点所在的索引,索引从0开始)

推导过程

初始状态:
在这里插入图片描述
存在双指针,slow、fast初始都指向链表的表头,slow的步长为1,fast的步长为2。
如果链表存在环,则slow与fast 一定会在环内相交 ,因为fast相对于slow的步长为1,即fast在一步一步的接近slow。
则有:
在这里插入图片描述
怎么求环的入口?
 设链表head到环入口的距离为x, 环入口到slow和fast相交点的距离为y,相交点到环入口的距离为z,则有:
在这里插入图片描述
slow和fast同时从链表头开始移动到相交分别移以下距离:
slow:x+y
fast: x+y+n(y+z)
(fast与slow相交之前可能已经在环中转了n圈,一圈距离为y+z)

因为fast的步长为slow的2倍则有:

2(x+y)= x+y+n(y+z)
--> x+y = n(y+z)
--> x = n(y+z)-y
--> x = (n-1)(y+z) + z

x = (n-1)(y+z) + z可以得知,x的长度等距离z加上n-1圈的环的距离((y+z)为一圈环的距离,且(n-1) >= 0)则有:

假如存在两个指针p1, p2, p1指向链表头部向着环入口出发,p2指向slow与fast的相交点向着环入口出发,p1和p2同时开始移动,
则p1与p2的相交点即为环入口。 (即p2从相交点移动到环入口(距离z)后可能会转(n-1)圈环)
在这里插入图片描述

Go

func detectCycle(head *ListNode) *ListNode {
	slow, fast := head, head

	// 如果存在环,fast.Next不可能为nil
	for fast != nil && fast.Next != nil {
		// slow的步长为1
		// fast的步长为2
		slow = slow.Next
		fast = fast.Next.Next

		// 当slow与fast相等时,说明在环内相交了
		if slow == fast {
			// 找出环的入口
			p1 := head
			p2 := slow
			// p1从链表头部开始移动,p2从相交点开始移动,两者相交的点即为环的入口
			for p1 != p2 {
				p1, p2 = p1.Next, p2.Next
			}

			return p1
		}
	}

	return nil
}

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

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

相关文章

JavaEE-自定义SSM-编写核心-解析yml文件

3.3.1 加载yml文件 编写yaml工厂&#xff0c;用于加载yml文件 package com.czxy.yaml;import java.io.InputStream;/*** 用于处理 application.yml文件* 1. 加载application.yml文件* 2. yaml工具类进行解析* Map<String, Map<String, Map<....>> >* …

[数据结构]-哈希

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 本期学习目标&…

代码随想录刷题笔记-Day12

1. 二叉树的递归遍历 144. 二叉树的前序遍历https://leetcode.cn/problems/binary-tree-preorder-traversal/94. 二叉树的中序遍历https://leetcode.cn/problems/binary-tree-inorder-traversal/145. 二叉树的后续遍历https://leetcode.cn/problems/binary-tree-postorder-tra…

混淆矩阵、准确率、查准率、查全率、DSC、IoU、敏感度的计算

1.背景介绍 在训练的模型的时候&#xff0c;需要评价模型的好坏&#xff0c;就涉及到混淆矩阵、准确率、查准率、查全率、DSC、IoU、敏感度的计算。 2、混淆矩阵的概念 所谓的混淆矩阵如下表所示&#xff1a; TP:真正类&#xff0c;真的正例被预测为正例 FN:假负类&#xf…

09. Springboot集成sse服务端推流

目录 1、前言 2、什么是SSE 2.1、技术原理 2.2、SSE和WebSocket 2.2.1、SSE (Server-Sent Events) 2.2.2、WebSocket 2.2.3、选择 SSE 还是 WebSocket&#xff1f; 3、Springboot快速集成 3.1、添加依赖 3.2、创建SSE控制器 3.2.1、SSEmitter创建实例 3.2.2、SSEmi…

K8s-持久化(持久卷,卷申明,StorageClass,StatefulSet持久化)

POD 卷挂载 apiVersion: v1 kind: Pod metadata:name: random-number spec:containers:- image: alpinename: alpinecommand: ["/bin/sh","-c"]args: ["shuf -i 0-100 -n 1 >> /opt/number.out;"]volumeMounts:- mountPath: /optname: da…

Ubuntu findfont: Font family ‘SimHei‘ not found.

matplotlib中文乱码显示 当我们遇到这样奇怪的问题时, 结果往往很搞笑 尝试1不行 Stopping Jupyter Installing font-manager: sudo apt install font-manager Cleaning the matplotlib cache directory: rm ~/.cache/matplotlib -fr Restarting Jupyter. 尝试2 This work fo…

AI大模型开发架构设计(6)——AIGC时代,如何求职、转型与选择?

文章目录 AIGC时代&#xff0c;如何求职、转型与选择&#xff1f;1 新职场&#xff0c;普通人最值钱的能力是什么?2 新职场成长的3点建议第1点&#xff1a;目标感第2点&#xff1a;执行力第3点&#xff1a;高效生产力 3 新职场会产生哪些新岗位机会?如何借势?4 新职场普通人…

微信小程序(十七)自定义组件生命周期(根据状态栏自适配)

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.获取手机状态栏的高度 2.验证attached可以修改数据 3.动态绑定样式数值 源码&#xff1a; myNav.js Component({lifetimes:{//相当于vue的created,因为无法更新数据被打入冷宫created(){},//相当于vue的mount…

【运行Python爬虫脚本示例】

主要内容&#xff1a;Python中的两个库的使用。 1、requests库&#xff1a;访问和获取网页内容&#xff0c; 2、beautifulsoup4库&#xff1a;解析网页内容。 一 python 爬取数据 1 使用requests库发送GET请求&#xff0c;并使用text属性获取网页内容。 然后可以对获取的网页…

基于python flask茶叶网站数据大屏设计与实现,可以做期末课程设计或者毕业设计

基于Python的茶叶网站数据大屏设计与实现是一个适合期末课程设计或毕业设计的项目。该项目旨在利用Python技术和数据可视化方法&#xff0c;设计和开发一个针对茶叶行业的数据大屏&#xff0c;用于展示和分析茶叶网站的相关数据。 项目背景 随着互联网的快速发展&#xff0c;越…

一张图区分Spring Task的3种模式

是的&#xff0c;只有一张图&#xff1a; fixedDelay 模式cron 模式fixedRate 模式

[HUBUCTF 2022 新生赛]ezPython

打开是一个pyc文件&#xff0c;我用的是pycdc进行反编译 # Source Generated with Decompyle # File: ezPython.pyc (Python 3.7)from Crypto.Util.number import * import base64 import base58 password open(password.txt, r).read() tmp bytes_to_long(password.encode(u…

基于JavaWeb开发的家具定制购买网站【附源码】

基于JavaWeb开发的家具定制购买网站【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#…

GLog开源库使用

Glog地址&#xff1a;https://github.com/google/glog 官方文档&#xff1a;http://google-glog.googlecode.com/svn/trunk/doc/glog.html 1.利用CMake进行编译&#xff0c;生成VS解决方案 &#xff08;1&#xff09;在glog-master文件夹内新建一个build文件夹&#xff0c;用…

docker-compose Install influxdb1+influxdb2+telegraf

influxd2前言 influxd2 是 InfluxDB 2.x 版本的后台进程,是一个开源的时序数据库平台,用于存储、查询和可视化时间序列数据。它提供了一个强大的查询语言和 API,可以快速而轻松地处理大量的高性能时序数据。 telegraf 是一个开源的代理程序,它可以收集、处理和传输各种不…

在Ubuntu上安装pycuda记录

1. 安装CUDA Toolkit 11.8 从MZ小师妹的摸索过程来看&#xff0c;其他版本的会有bug&#xff0c;12.0的版本太高&#xff0c;11.5的太低&#xff08;感谢小师妹让我少走弯路&#xff09; 参考网址&#xff1a;CUDA Toolkit 11.8 Downloads | NVIDIA Developer 在命令行输入命…

调用阿里通义千问大语言模型API-小白新手教程-python

阿里大语言模型通义千问API使用新手教程 最近需要用到大模型&#xff0c;了解到目前国产大模型中&#xff0c;阿里的通义千问有比较详细的SDK文档可进行二次开发,目前通义千问的API文档其实是可以进行精简然后学习的,也就是说&#xff0c;是可以通过简单的API调用在自己网页或…

Vue<圆形旋转菜单栏效果>

效果图&#xff1a; 大家不一定非要制成菜单栏&#xff0c;可以看下人家的华丽效果&#x1f61d;&#xff0c;参考地址 https://travelshift.com/ 大佬写的效果可比我的强多了&#xff0c;但是无从下手&#xff0c;所以就自己琢磨怎么写了&#xff0c;只能说效果勉强差不多 可…

“steam教学理念”scratch+数学 ——时钟案例

一、时钟概念 它通常由一个圆形表盘组成&#xff0c;表盘上有12个数字&#xff0c;分别是1到12。这些数字代表了小时。在表盘上&#xff0c;还有三根指针&#xff0c;一根较短的指针叫做时针&#xff0c;另一根较长的指针叫做分针&#xff0c;而秒针通常为红色&#xff0c;且指…
最新文章