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

news2024/11/24 13:08:12

题目链接: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.coloradmin.cn/o/1415631.html

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

相关文章

Android Handler完全解读

一&#xff0c;概述 Handler在Android中比较基础&#xff0c;本文笔者将对此机制做一个完全解读。读者可简单参考上述类图与时序图&#xff0c;便于后续理解。 二&#xff0c;源码解读 1&#xff0c;主线程伊始 众所周知&#xff0c;通过Zygote的fork方式&#xff0c;新创建…

腾讯云轻量应用Ubuntu服务器如何一键部署幻兽帕鲁Palworld私服?

幻兽帕鲁/Palworld是一款2024年Pocketpair开发的开放世界生存制作游戏&#xff0c;在帕鲁的世界&#xff0c;玩家可以选择与神奇的生物“帕鲁”一同享受悠闲的生活&#xff0c;也可以投身于与偷猎者进行生死搏斗的冒险。而帕鲁可以进行战斗、繁殖、协助玩家做农活&#xff0c;也…

网页转文件下载工具

为了更快捷copy博客 做了个 网页转文件下载工具 1.0.1 更新如下&#xff1a; javaphpjava提供页面转换文件的微服务APIphp调用接口&#xff0c;输出文件下载支持网页转md 1.0.2 更新如下&#xff1a; 样式表切换&#xff0c;白天or黑夜&#xff0c;cookie七天保质期 未…

全国首条智慧高速开通,“车牌付” 会取代传统 ETC 收费吗?

2024年1月19日&#xff0c;全国首条智慧高速--杭绍甬高速杭绍段正式建成通车&#xff01;项目全长约52.8公里&#xff0c;设计速度120公里/小时&#xff0c;是长三角智慧交通示范项目。 01 杭绍甬 “慧眼”感知系统 全国首条智慧高速公路--杭绍甬高速在视频AI算法、IoT物联网、…

SpringBoot系列之MybatisPlus实现分组查询

SpringBoot系列之MybatisPlus实现分组查询 我之前博主曾记写过一篇介绍SpringBoot2.0项目怎么集成MybatisPlus的教程&#xff0c;不过之前的博客只是介绍了怎么集成&#xff0c;并没有做详细的描述各种业务场景&#xff0c;本篇博客是对之前博客的补充&#xff0c;介绍在mybat…

mac裁剪图片

今天第一次用mac裁剪图片&#xff0c;记录一下过程&#xff0c;差点我还以为我要下载photoshop了&#xff0c; 首先准备好图片 裁剪的目的是把图片的标题给去掉&#xff0c;但是不能降低分辨率&#xff0c;否则直接截图就可以了 解决办法 打开原始图片(不要使用预览&#xf…

【机器学习笔记】0 基础知识之python基础

注&#xff1a;本文内容仅为个人学习笔记&#xff0c;教程为黄海广老师主讲的机器学习入门系列&#xff0c; 课程链接&#xff08;中国大学慕课&#xff0c;有习题和证书&#xff09; 课程资源&#xff08;pdf版本课件和代码&#xff09;公布在Github链接 课程视频也可以在b站观…

python10-Python的字符串之拼接字符串

如果直接将两个字符串紧挨着写在一起&#xff0c;Python就会自动拼接它们&#xff0c;例如如下代码。 s1 "软件测试划水老师傅&#xff0c;"软件测试老痞print(s1) 上面代码将会输出: 软件测试划水老师傅&#xff0c;软件测试老痞 上面这种写法只是书写字符串的一…

数学知识第三期 欧拉函数

前言 相信大家在高中的时候接触过欧拉函数&#xff0c;希望大家通过本篇文章能够进一步理解欧拉函数&#xff01;&#xff01;&#xff01; 一、什么是欧拉函数&#xff1f; 欧拉函数是一个在数论中用于描述特定正整数的互质数的概念。具体来说&#xff0c;对于一个正整数n&…

初识人工智能,一文读懂机器学习之逻辑回归知识文集(7)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

电商API接口|爬虫案例|采集某东商品评论信息

前言&#xff1a; 平常大家都有网上购物的习惯&#xff0c;在商品下面卖的好的产品基本都会有评论&#xff0c;当然也不排除有刷评论的情况&#xff0c;因为评论会影响我们的购物决策。今天主要分享用pythonre正则表达式获取京东商品评论。API接口获取京东平台商品详情SKU数据…

API网关-Apinto压缩包方式自动化安装配置教程

文章目录 前言一、Apinto安装教程1. 复制脚本2. 增加执行权限3. 执行脚本4. Apinto命令4.1 启动Apinto4.2 停止Apinto4.3 重启Apinto4.4 查看Apinto版本信息4.5 加入Apinto集群4.6 离开Apinto集群4.7 查看Apinto节点信息 5. 卸载Apinto 二、Apserver(Apinto Dashboard V3)安装教…

powermock: 一个支持 gRPC 的 Mock Server

文章目录 背景选型架构安装配置使用教程快速开始接口定义配置启动 Mock 规则redis 插件HTTP Mock高级配置前置准备场景一 特定 ID 返回特定用户信息场景二 通过脚本返回用户数据 总结参考资料 本文介绍的是如何基于 bilibili 的开源方案 powermock 搭建一套通用的适用于自己公司…

11. 双目视觉之立体视觉基础

目录 1. 深度恢复1.1 单目相机缺少深度信息1.2 如何恢复场景深度&#xff1f;1.3 深度恢复的思路 2. 对极几何约束2.1 直观感受2.2 数学上的描述 1. 深度恢复 1.1 单目相机缺少深度信息 之前学习过相机模型&#xff0c;最经典的就是小孔成像模型。我们知道相机通过小孔成像模…

uniapp scroll-view用法[下拉刷新,触底事件等等...](4)

前言:可滚动视图区域。用于区域滚动 话不多说 直接上官网属性 官网示例 讲一下常用的几个 scroll 滚动时触发 scrolltoupper 滚动到顶部或左边&#xff0c;会触发 scrolltoupper 事件 scrolltolower 滚动到底部或右边&#xff0c;会触发 scrolltolower 事件 1.纵向滚动…

【揭秘】RecursiveAction全面解析

内容概要 RecursiveAction是Java中一个强大的工具&#xff0c;它允许将复杂任务分解为更小的子任务&#xff0c;这些子任务可以并行执行&#xff0c;从而提高整体性能&#xff0c;其主要优点在于能够有效地利用多核处理器&#xff0c;减少任务执行时间&#xff0c;并简化并行编…

SQL注入:盲注

SQL注入系列文章&#xff1a; 初识SQL注入-CSDN博客 SQL注入&#xff1a;联合查询的三个绕过技巧-CSDN博客 SQL注入&#xff1a;报错注入-CSDN博客 目录 什么是盲注&#xff1f; 布尔盲注 手工注入 使用python脚本 使用sqlmap 时间盲注 手工注入 使用python脚本 使…

SpringBoot项目配置SSL后,WebSocket连接失败的解决方案

SpringBoot项目配置SSL后&#xff0c;WebSocket连接应使用wss协议&#xff0c;而不是ws协议。在前端配置WebSocket时&#xff0c;URL以wss://开头。

【计算机网络】中小型校园网构建与配置

拓扑图配置文件传送门 Packet Tracer-中小型校园网配置布局文件文件 相关文章 【计算机网络】IP协议及动态路由算法 【计算机网络】Socket通信编程与传输协议分析 【计算机网络】网络应用通信基本原理 原理 1. Network 广域网&#xff0c;WAN Wide Area Network&#xff…

记录浏览器能打开github.com,android studio无法拉取github项目,并且ping github.com也拼不通的问题

问题&#xff1a; Android studio编译flutter工程突然碰上如下问题&#xff1a; 在浏览器打开该地址能正常打开&#xff0c;尝试ping&#xff1a; 解决方式 通过搜索&#xff0c;查到如下办法&#xff1a; 1、首先在ipaddress.com中查询github.com域名的固定ip地址&#xff…