快慢指针及原理证明(swift实现)
目录
- 链表
- 快慢指针
- 一、快慢指针基本介绍
- 二、快慢指针之找特殊节点
- 1.删除链表的倒数第k个结点
- 题目描述
- 解题思路
- 2.链表的中间节点
- 题目描述
- 解题思路
- 三、快慢指针之环形问题
- 1.判断环形链表
- 题目描述
- 解题思路
- 2.判断环形链表并返回入环节点
- 题目描述
- 解题思路
- 3.变种——判断快乐数
- 题目描述
- 解题思路
- 四、快慢指针的优势
- 五、快慢指针在实际项目中的应用
链表
链表的结构很简单,由指针把若干个节点连接成链状结构。链表是一种动态的数据结构,因为在创建链表时,无须知道链表的长度。当插入一个节点时,我们只需为新节点分配内存,然后调整指针的指向来确保新节点被链接到链表当中。内存分配不是在创建链表时一次性完成,而是在每添加一个节点分配一次内存。由于没有闲置的内存,链表的空间效率比数组高。
public class ListNode {public var val: Intpublic var next: ListNode?public init() { self.val = 0; self.next = nil; }public init(_ val: Int) { self.val = val; self.next = nil; }public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
}
快慢指针
一、快慢指针基本介绍
快慢指针是一种双指针技巧,常用于遍历链表或是数组。顾名思义,就是两个指针同时遍历链表,但移动速度不同,一个走得快,一个走得慢,根据问题的需要来确定指针指向的位置和指针的走向、速度。使用快慢指针算法可以极大简化算法的时间复杂度,提高程序的效率。
注意: 这里的快慢指针并不是严格的指针类型,而是可以指向具体位置的变量,一般在数组中使用下标,在链表中使用链表的节点指针。
二、快慢指针之找特殊节点
简介:快慢指针一般可以用来找特殊节点的位置,一般让快慢指针相隔一定距离,当快指针走到尾时,慢指针则停在你要找的位置上。
经典例题:
1.删除链表的倒数第k个结点
题目描述
给你一个链表,删除链表的倒数第 k 个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], k = 2 输出:[1,2,3,5]
示例 2:
输入:head = [1], k = 1 输出:[]
示例 3:
输入:head = [1,2], k = 1 输出:[1]
数据范围:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= k <= sz
进阶:你能尝试使用一趟扫描实现吗?
解题思路
- 解法1——遍历2次链表
为了得到倒数第 k k k个节点,很自然的想法是先走到链表的尾端,再从尾部回溯 k k k步。可是我们从链表节点的定义可以看出,本题中的链表是单向链表,单向链表的节点只有从前往后的指针没有从后往前的指针,因此这种思路行不通。既然不能从尾节点开始遍历这个链表,我们还是把思路回到头节点上来。假设整个链表有 n n n个节点,那么倒数第 k k k个节点就是从头节点开始的第 n − k + 1 n-k+1 n−k+1个节点。如果我们能够得到链表中节点的个数 n n n,那么只要从头节点开始往后走 n − k + 1 n-k+1 n−k+1步就可以了。如何得到节点数 n n n?只需从头开始遍历链表,每经过一个节点,计数器加1即可。也就是说我们需要遍历链表两次,第一次统计出链表中节点的个数 n n n,第二次就能找到倒数第 k k k个点。
以head = [1,2,3,4,5], k = 3为例 —> [1,2,4,5]
- 解法2——遍历1次链表
为了实现制遍历链表一次就能找到倒数第k个节点,我们可以利用快慢指针算法。先让快指针先走 k k k步,然后让快慢指针同时走,当快指针走到链表的尾部时,慢指针停在倒数第 k k k个节点。
小技巧:涉及链表删除操作的可以加一个虚拟头节点来防止删除节点为链表的头节点、删完为空等特殊情况,可以减少特判。
退回前一步
func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {guard head != nil, n > 0 else {return nil}var dummy = ListNode(-1)dummy.next = headvar fast: ListNode? = dummyvar slow: ListNode? = dummyfor _ in 1...n {fast = fast?.next}while fast?.next != nil {fast = fast?.nextslow = slow?.next}slow?.next = slow?.next?.nextreturn dummy.next}
2.链表的中间节点
题目描述
给你单链表的头结点 head ,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:head = [1,2,3,4,5]
输出:[3,4,5]
解释:链表只有一个中间结点,值为 3 。
示例 2:
输入:head = [1,2,3,4,5,6]
输出:[4,5,6]
解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。
数据范围:
链表的结点数范围是 [1, 100]
1 <= Node.val <= 100
解题思路
- 解法1——遍历2次链表
先遍历一次链表算出长度,并对链表长度为奇数还是偶数做分类处理,通过计算后再次遍历链表,返回中间节点。
- 解法2——遍历1次链表
使用快慢指针的方法只需遍历一次链表,让快指针一次走两步,慢指针一次走一步,当快指针走到尾时,慢指针则停在题目需要的位置,也无需对链表长度做分类处理。
链表长度为奇数,slow在中间结点,fast在最后一个节点上
链表长度为偶数,slow在第二个中间结点,fast指向NULL
func middleNode(_ head: ListNode?) -> ListNode? {var slow = headvar fast = headwhile fast != nil && fast?.next != nil {slow = slow?.nextfast = fast?.next?.next}return slow}
判断链表的长度是否为奇数:如果fast非NULL,说明长度为奇数
func isLengthOdd(_ head: ListNode?) -> Bool {var slow = headvar fast = headwhile fast != nil && fast?.next != nil {slow = slow?.nextfast = fast?.next?.next}return fast != nil // 如果fast非NULL,说明长度为奇数}
三、快慢指针之环形问题
简介:快慢指针还可以解决带环问题,例如判断链表是否带环,或返回链表入环的第一个节点。
经典例题:
1.判断环形链表
题目描述
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
数据范围:
链表中节点的数目范围是 [ 0 , 1 0 4 ] \lbrack 0, 10^4 \rbrack [0,104]
− 1 0 5 ≤ N o d e . v a l ≤ 1 0 5 -10^5 \le Node.val \le 10^5 −105≤Node.val≤105
pos
为-1
或者链表中的一个 有效索引 。
进阶:你能用 O(1)(即,常量)内存解决此问题吗?
解题思路
定义两个快慢指针,慢指针一次走一步,快指针一次走两步,如果链表有环,快指针和慢指针最终会相遇;如果没有环,快指针将会到达链表的末尾(即指向NULL)。
不带环
fast指向NULL,slow指向中点
带环
fast 和 slow 在环上某点相遇
A 是起点,B 是环的入口,slow
刚走到入环点 B 时,fast
在环中走了 n n n圈最终的位置为 C,AB 之间的距离是 x x x,从 B 点顺时针走到 C 的距离是 y y y,从 C 点顺时针走到 B 的距离是 z z z。环的总长度 s = y + z s=y+z s=y+z。
Q1:链表有环的情况下,为什么快慢指针一定会相遇?
假设slow
刚走到入环点 B 时,fast
的刚好走到 C ,此时两个指针的距离为 z z z。
而fast
每次走两步,slow
每次走一步,快指针速度差为1,则每走一次,二者之间的距离就减1。所以经过z次移动,两者一定会相遇。
打个比方来理解slow,fast之间的关系,好比在环形跑道上 A 同学和 B 同学之间距离未知,但 A 同学的速度是 B 同学的两倍,在未来的某一时刻两者一定会相遇。
Q2:快指针速度差不为一时,是否会永远不相遇?
以 fast每次走3步 slow每次走1步
为例:
fast
每次走3步,slow
每次走1步,快指针速度差为2,则每走一次,二者之间的距离就减2。
-
经过 k k k次之后两者之间的距离为 z − 2 k z-2k z−2k。
-
当 z z z为偶数时,则距离一定会变为0,即相遇;
-
当 z z z为奇数时,则距离会逐渐递减为-1(N-2, N-4, …, 3, 2, -1)(这里的-1是指fast领先slow指针一步),两指针错过。那么接下去fast和slow还会不会相遇呢?
-
假设环的总长度 s s s,则此时两个指针的距离变成 s − 1 s-1 s−1,同理
-
当 s − 1 s-1 s−1为偶数时,即 s s s为奇数时,则一定会相遇
- 当 s − 1 s-1 s−1为奇数时,即 s s s为偶数时,则二者之间的距离最终又会变为-1,一直错过无法相遇。
总结:当 z z z为奇数, s s s为偶数时,二者一直错过,无法相遇。
s是偶数且z是奇数,这个条件能同时满足吗?
当slow
刚走到入环点 B 时,走过的路程用 L _ s l o w L\_{slow} L_slow表示,则有 L _ s l o w = x L\_{slow} = x L_slow=x,fast
走过的路程用 L _ f a s t L\_{fast} L_fast表示,则有 L _ f a s t = x + n s + s − z L\_{fast} = x + ns + s-z L_fast=x+ns+s−z。
因为fast每次走3步 slow每次走1步
,所以有:
3 L _ s l o w = L _ f a s t 3 x = x + n s + s − z 2 x = ( n + 1 ) s − z z = ( n + 1 ) s − 2 x \begin{align} 3L\_{slow} &= L\_{fast} \notag \\ 3x&=x+ns+ s-z \notag \\ 2x&=(n+1)s-z \notag \\ z&= (n+1)s-2x \notag \\ \end{align} 3L_slow3x2xz=L_fast=x+ns+s−z=(n+1)s−z=(n+1)s−2x
s s s是偶数, 2 x 2x 2x也是偶数,偶数减偶数一定是偶数,所以 z z z一定是偶数,不可能是奇数,所以此条件不可能同时成立,fast
与slow
一定会相遇。
fast每次走k步 slow每次走1步
的情况以此类推。只要slow每次走1步,fast每次走比slow快,就一定会相遇。
slow每次走的步数不是1呢?
AI给出的答案是依旧一定会相遇
,证明就交给读者自行思考了。
如果fast每次移动 k k k步,slow每次移动 s s s 步(其中 k > s ≥ 1 k > s \geq1 k>s≥1),它们的相对速度是 k − s k - s k−s。假设一共走了 t t t次,两者在环上的某点相遇时,
fast
走了 n _ 1 n\_1 n_1圈,slow
走了 n _ 2 n\_2 n_2圈,环的长度为 l l l,则两者的总路程之差为 ( n _ 1 − n _ 2 ) ⋅ l (n\_1-n\_2) \cdot l (n_1−n_2)⋅l。令 n = n _ 1 − n _ 2 n=n\_1-n\_2 n=n_1−n_2,则有 n ⋅ l = ( k − s ) ⋅ t n \cdot l =(k-s) \cdot t n⋅l=(k−s)⋅t。
即: ( k − s ) ⋅ t = n ⋅ l (k-s) \cdot t=n \cdot l (k−s)⋅t=n⋅l【其中 k , s , l k,s,l k,s,l是正整数 k > s ≥ 1 k > s \geq1 k>s≥1 】证明恒有整数解 t t t和整数解 n n n。
AI证明过程如下:
![]()
func hasCycle(_ head: ListNode?) -> Bool {var fast = headvar slow = headwhile fast != nil && fast?.next != nil {fast = fast?.next?.nextslow = slow?.nextif fast === slow {return true}}return false}
2.判断环形链表并返回入环节点
题目描述
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置**(索引从 0 开始)**。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
数据范围:
链表中节点的数目范围在范围 [ 0 , 1 0 4 ] \lbrack 0, 10^4 \rbrack [0,104]内
− 1 0 5 ≤ N o d e . v a l ≤ 1 0 5 -10^5 \le Node.val \le 10^5 −105≤Node.val≤105
pos
为-1
或者链表中的一个 有效索引 。
进阶:你是否可以使用 O(1) 空间解决此题?
解题思路
- 解法1——(链表,快慢指针扫描) 时间复杂度 O(n) 空间复杂度 O(1)
用两个指针 slow
、fast
分别从起点开始走,slow
每次走一步,fast
每次走两步。如果过程中 fast
走到nil,则说明不存在环。否则当 slow
和 fast
相遇后,让slow
返回起点,fast
待在原地不动,然后两个指针每次分别走一步,当再次相遇时,相遇点就是环的入口。
证明:如上图所示,a是起点,b是环的入口,c是两个指针的第一次相遇点,ab之间的距离是x,bc之间的距离是y,从 c 点顺时针走到 b 的距离是z。则第一次相遇时,slow
所走的距离是 x + y x + y x+y, fast
所走的距离是 x + ( y + z ) ⋅ n + y x + \lparen y + z \rparen \cdot n + y x+(y+z)⋅n+y, n n n 表示圈数,同时 fast
走过的距离是 slow
的两倍,也就是 2 ( x + y ) 2 \lparen x + y \rparen 2(x+y) ,所以我们有 x + ( y + z ) ⋅ n + y = 2 ( x + y ) x + \lparen y + z \rparen \cdot n + y = 2 \lparen x + y \rparen x+(y+z)⋅n+y=2(x+y),所以 x = ( n − 1 ) × ( y + z ) + z x = \lparen n - 1\rparen \times \lparen y + z \rparen + z x=(n−1)×(y+z)+z。那么我们让 fast
从 c点开始走,走 x 步,会恰好走到 b点;让 slow
从 a 点开始走,走 x 步,也会走到 b 点。
x + ( y + z ) ⋅ n + y = 2 ( x + y ) x + ( n + 1 ) y + n z = 2 x + 2 y ( n − 1 ) y + n z = x ( n − 1 ) y + ( n − 1 ) z + z = x x = ( n − 1 ) × ( y + z ) + z \begin{align} x + \lparen y + z \rparen \cdot n + y &= 2 \lparen x + y \rparen \notag \\ x + \lparen n + 1\rparen y + nz &= 2x + 2y \notag \\ \lparen n - 1 \rparen y + nz &= x \notag \\ \lparen n - 1 \rparen y + \lparen n - 1 \rparen z + z &= x \notag \\ x &= \lparen n - 1\rparen \times \lparen y + z \rparen + z \notag \end{align} x+(y+z)⋅n+yx+(n+1)y+nz(n−1)y+nz(n−1)y+(n−1)z+zx=2(x+y)=2x+2y=x=x=(n−1)×(y+z)+z
时间复杂度
slow
总共走了 2 x + y 2x+y 2x+y步,fast
总共走了 2 x + 2 y + x 2x+2y+x 2x+2y+x步,所以两个指针总共走了 5 x + 3 y 5x+3y 5x+3y步。
从图中可以看出 y y y小于等于环的长度,所以 x + y x+y x+y 小于等于链表总长度 n n n。所以总时间复杂度是 O(n)。
func detectCycle(_ head: ListNode?) -> ListNode? {var fast = headvar slow = headwhile fast != nil && fast?.next != nil {slow = slow?.nextfast = fast?.next?.nextif fast === slow {slow = headwhile slow !== fast {slow = slow?.nextfast = fast?.next}return slow}}return nil}
- 解法2——面向测试用例编程,利用val的范围,相当于将走过的节点标记了,第二次走就会被发现。
− 1 0 5 < = N o d e . v a l < = 1 0 5 -10^5 <= Node.val <= 10^5 −105<=Node.val<=105
func detectCycle(_ head: ListNode?) -> ListNode? {let maxVal = 100000var pointer = headwhile pointer != nil {if pointer?.val ?? 0 > maxVal {pointer?.val -= 2 * maxValreturn pointer}pointer?.val += 2 * maxValpointer = pointer?.next}return nil}
3.变种——判断快乐数
题目描述
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
- 如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
示例 1:
输入:n = 19
输出:true
解释:
1 2 + 9 2 = 82 8 2 + 2 2 = 68 6 2 + 8 2 = 100 1 2 + 0 2 + 0 2 = 1 \begin{align} &1^2 + 9^2 = 82 \notag &&\\ &8^2 + 2^2 = 68\notag &&\\ &6^2 + 8^2 = 100 \notag &&\\ &1^2 + 0^2 + 0^2 = 1 \notag &&\\ \end{align} 12+92=8282+22=6862+82=10012+02+02=1
示例 2:
输入:n = 2
输出:false
解释:
2 2 = 4 4 2 = 16 1 2 + 6 2 = 37 3 2 + 7 2 = 58 5 2 + 8 2 = 89 8 2 + 9 2 = 145 1 2 + 4 2 + 5 2 = 42 4 2 + 2 2 = 20 \begin{align} &2^2 = 4 \notag &&\\ &4^2 = 16 \notag &&\\ &1^2 + 6^2 = 37 \notag &&\\ &3^2 + 7^2 = 58 \notag &&\\ &5^2 + 8^2 = 89 \notag &&\\ &8^2 + 9^2 = 145 \notag &&\\ &1^2 + 4^2+ 5^2 = 42 \notag &&\\ &4^2 + 2^2 = 20 \notag &&\\ \end{align} 22=442=1612+62=3732+72=5852+82=8982+92=14512+42+52=4242+22=20
解题思路
不论一个数是不是快乐数,在经历上述转换都会形成一个环,区别在于快乐数形成的环中数全为 1 ,非快乐数形成的环中数全不为 1 ,则可以用到快慢指针的方法,因为快慢指针会在环上的某处相遇,所以判断相遇处,即环中数是否为 1 ,如果为 1 则是快乐数,反之不是快乐数。
此题目的双指针并不是严格意义上的指针,而是用两个变量,fast 变量一次进行两次转换,slow 变量一次进行一次转换,两变量相等即为在环中相遇,判断相遇的数是否为 1。
快乐数19
非快乐数2
class Solution {func sum(_ n: Int) -> Int {var cnt = 0var num = nwhile num > 0 {cnt += (num % 10) * (num % 10)num /= 10}return cnt}func isHappy(_ n: Int) -> Bool {var slow = nvar fast = nslow = sum(slow)fast = sum(sum(fast))while fast != slow {fast = sum(sum(fast))slow = sum(slow)}return slow == 1}
}
四、快慢指针的优势
-
线性时间复杂度:快慢指针能够在O(n)时间内完成遍历,比暴力方法更高效。
-
实时处理:无需额外存储大规模数据,可以在流式日志处理中使用。
-
灵活性:可以通过调整指针步长和条件逻辑,适应多种分析需求。
五、快慢指针在实际项目中的应用
快慢指针不仅在算法竞赛中频繁出现,在实际项目开发中也有广泛应用。以下是几个应用示例:
-
垃圾回收算法:在某些编程语言的垃圾回收算法中,快慢指针可以用于检测对象引用图中的环,帮助垃圾回收器更高效地回收内存。
-
网络包处理:在网络编程中,快慢指针可以用于处理网络包链表,帮助快速定位特定的网络包,提高数据传输效率。
-
日志分析:在日志分析系统中,快慢指针可以用于遍历和分析时间序列数据,帮助快速定位异常事件或特定时间点的数据。
- 定位异常事件
- 目标:在时间序列日志中快速定位某个事件(如请求超时或错误码)。
- 方法:
- 慢指针逐步遍历日志,记录正常事件的时间或内容。
- 快指针跳跃式地检查是否有异常事件(如响应时间超过阈值、错误码出现等)。
logs = [(timestamp, event) for timestamp, event in log_data]
slow, fast = 0, 0
while fast < len(logs):if is_abnormal(logs[fast]): # 判断是否为异常事件print(f"异常事件发生在时间点: {logs[fast][0]}")fast += 1
- 寻找特定时间窗口的数据
- 目标:找到满足某条件的连续时间窗口(如访问量大于某阈值的窗口)。
- 方法:
- 慢指针标记窗口起点,快指针扩展窗口。
- 检查窗口内的数据是否符合条件。
logs = [(timestamp, value) for timestamp, value in log_data]
slow, fast = 0, 0
window_sum = 0
while fast < len(logs):window_sum += logs[fast][1]while window_sum > threshold: # 如果窗口满足条件print(f"满足条件的窗口: {logs[slow][0]} 至 {logs[fast][0]}")window_sum -= logs[slow][1]slow += 1fast += 1
- 查找重复事件
- 目标:检测是否有重复事件或周期性模式。
- 方法:
- 快慢指针用于比较不同时间段的数据。
- 如果发现两个指针指向的事件内容相同,记录下该事件。
logs = [event for timestamp, event in log_data]
slow, fast = 0, 1
while fast < len(logs):if logs[slow] == logs[fast]: # 检测重复print(f"重复事件: {logs[slow]} 在 {slow} 和 {fast} 位置")slow += 1fast += 1
相关文章:
快慢指针及原理证明(swift实现)
目录 链表快慢指针一、快慢指针基本介绍二、快慢指针之找特殊节点1.删除链表的倒数第k个结点题目描述解题思路 2.链表的中间节点题目描述解题思路 三、快慢指针之环形问题1.判断环形链表题目描述解题思路 2.判断环形链表并返回入环节点题目描述解题思路 3.变种——判断快乐数题…...
web前端3--css
注意(本文一切代码一律是在vscode中书写) 1、书写位置 1、行内样式 //<标签名 style"样式声明"> <p style"color: red;">666</p> 2、内嵌样式 1、style标签 里面写css代码 css与html之间分离 2、css属性:值…...
一文大白话讲清楚webpack基本使用——5——babel的配置和使用
文章目录 一文大白话讲清楚webpack基本使用——5——babel的配置和使用1. 建议按文章顺序从头看,一看到底,豁然开朗2. babel-loader的配置和使用2.1 针对ES6的babel-loader2.2 针对typescript的babel-loader2.3 babel配置文件 一文大白话讲清楚webpack基…...
Python自动化运维:一键掌控服务器的高效之道
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在互联网和云计算高速发展的今天,服务器数量的指数增长使得手动运维和管理变得异常繁琐。Python凭借其强大的可读性和丰富的生态系统,成为…...
基于quartz,刷新定时器的cron表达式
文章目录 前言基于quartz,刷新定时器的cron表达式1. 先看一下测试效果2. 实现代码 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。 而且听说点赞的人每天的运气都不会太差&…...
HTML常用属性
HTML标签的常见属性包括许多不同的功能,可以为元素提供附加信息或控制元素的行为。以下是一些常见的属性及其解释: 1. src 描述:src(source)属性指定一个资源的路径,通常用于图像、音频、视频等标签。常见…...
在 Babylon.js 中使用 Gizmo:交互式 3D 操作工具
在 3D 应用程序中,交互式操作对象(如平移、旋转、缩放)是一个常见的需求。Babylon.js 提供了一个强大的工具——Gizmo,用于在 3D 场景中实现这些功能。本文将介绍如何在 Babylon.js 中使用 Gizmo,并展示如何通过代码实…...
蓝桥杯练习日常|递归-进制转换
蓝桥云课760数的计算 一、递归 题目: 我的解题代码: #include <iostream> using namespace std; int sum0; int main() {// 请在此输入您的代码int n;cin>>n;int fun(int n);fun(n); cout<<sum<<\n;return 0; } // void fu…...
LabVIEW滤波器选择与参数设置
在信号处理应用中,滤波器是去除噪声、提取目标信号的重要工具。LabVIEW 提供多种类型的滤波器(如低通、高通、带通、带阻),用户需要根据采样频率、信号特性和应用需求合理选择滤波器类型及参数设置。本文以 采样率 100kHz…...
【c语言日寄】Vs调试——新手向
【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…...
C#中的Timers.Timer使用用法及常见报错
System.Timers.Timer 是一个基于服务器的计时器,它可以在应用程序中定期触发事件。这个计时器特别适合用于多线程环境,并且不应该与用户界面(UI)直接交互。在 ASP.NET 中,通常使用 System.Timers.Timer 来处理周期性的任务。 主要使用步骤&am…...
chrome小插件:长图片等分切割
前置条件: 安装有chrome谷歌浏览器的电脑 使用步骤: 1.打开chrome扩展插件 2.点击管理扩展程序 3.加载已解压的扩展程序 4.选择对应文件夹 5.成功后会出现一个扩展小程序 6.点击对应小程序 7.选择图片进行切割,切割完成后会自动保存 代码…...
mysql数据被误删的恢复方案
文章目录 一、使用备份恢复二、使用二进制日志(Binary Log)三、使用InnoDB表空间恢复四、使用第三方工具预防措施 数据误删是一个严重的数据库管理问题,但通过合理的备份策略和使用适当的恢复工具,可以有效地减少数据丢失的风险…...
K8S-Pod资源清单的编写,资源的增删改查,镜像的下载策略
1. Pod资源清单的编写 1.1 Pod运行单个容器的资源清单 ##创建工作目录 mkdir -p /root/manifests/pods && cd /root/manifests/pods vim 01-nginx.yaml ##指定api版本 apiVersion: v1 ##指定资源类型 kind: Pod ##指定元数据 metadata:##指定名称name: myweb ##用户…...
Unity Line Renderer Component入门
Overview Line Renderer 组件是 Unity 中用于绘制连续线段的工具。它通过在三维空间中的两个或两个以上的点的数组,并在每个点之间绘制一条直线。可以绘制从简单的直线到复杂的螺旋线等各种图形。 1. 连续性和独立线条 连续性:Line Renderer 绘制的线条…...
计算机工程:解锁未来科技之门!
计算机工程与应用是一个充满无限可能性的领域。随着科技的迅猛发展,计算机技术已经深深渗透到我们生活的方方面面,从医疗、金融到教育,无一不在彰显着计算机工程的巨大魅力和潜力。 在医疗行业,计算机技术的应用尤为突出。比如&a…...
翻译:How do I reset my FPGA?
文章目录 背景翻译:How do I reset my FPGA?1、Understanding the flip-flop reset behavior2、Reset methodology3、Use appropriate resets to maximize utilization4、Many options5、About the author 背景 在写博客《复位信号的同步与释放(同步复…...
在Unity中使用大模型进行离线语音识别
文章目录 1、Vosk下载下载vosk-untiy-asr下载模型在项目中使用语音转文字音频转文字2、whisper下载下载unity项目下载模型在unity中使用1、Vosk 下载 下载vosk-untiy-asr Github链接:https://github.com/alphacep/vosk-unity-asr 进不去Github的可以用网盘 夸克网盘链接:h…...
SpringBoot+Vue使用Echarts
前言 在vue项目中使用echarts,本次演示是使用vue2 1 前端准备 echarts官网: https://echarts.apache.org/zh/index.html 官网提供了基本的使用说明和大量的图表 1.1 下载echarts 执行命令 npm install echarts 直接这样执行很可能会失败,…...
【QT】-explicit关键字
explicit explicit 是一个 C 关键字,用于修饰构造函数。它的作用是防止构造函数进行隐式转换。 为什么需要 explicit? 在没有 explicit 的情况下,构造函数可以用于隐式类型转换。这意味着,如果你有一个接受某种类型的参数的构造…...
docker: Device or resource busy
(base) [rootbddx-vr-gpu-bcc2 /]#rm -rf /ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/ rm: cannot remove ‘/ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/merged’: Device or re…...
Vue - toRefs() 和 toRef() 的使用
一、toRefs() 在 Vue 3 中,toRefs()可以将响应式对象的属性转换为可响应的 refs。主要用于在解构响应式对象时,保持属性的响应性。 1. 导入 toRefs 函数 import { toRefs } from vue;2. 将响应式对象的属性转换为 ref const state reactive({count: 0,message:…...
(2024,MLLM,Healthcare,综述)多模态学习是否已在医疗保健领域实现通用智能?
Has Multimodal Learning Delivered Universal Intelligence in Healthcare? A Comprehensive Survey 目录 0. 摘要 1. 简介 5. MLLM 5.1 模态编码器与跨模态适配器 5.1.1 图像编码器 (Image Encoder) 5.1.2 语言模型 (Language Model) 5.1.3 跨模态适配器 (Cross-moda…...
css命名规范——BEM
目录 引言 BEM是什么? 块Block 元素Element 修饰语Modifier BEM解决了哪些问题? 在流行框架的组件中使用 BEM 格式 实战 认识设计图 如何使用当前的css规范正确命名? 引言 css样式类命名难、太难了,难于上青天,这个和js变量命名还不一样。看看项目中五花八门的样…...
使用PHP函数 “is_object“ 检查变量是否为对象类型
在PHP中,变量可以保存不同类型的值,包括整数、字符串、数组、布尔值等等。其中,对象是一种特殊的数据类型,用于封装数据和方法。在处理PHP代码中,我们经常需要检查一个变量是否为对象类型,以便进行相应的处…...
Golang:使用DuckDB查询Parquet文件数据
本文介绍DuckDB查询Parquet文件的典型应用场景,掌握DuckDB会让你的产品分析能力更强,相反系统运营成本相对较低。为了示例完整,我也提供了如何使用Python导出MongoDB数据。 Apache Parquet文件格式在存储和传输大型数据集方面变得非常流行。最…...
Moretl FileSync增量文件采集工具
永久免费: <下载> <使用说明> 我们希望Moretl FileSync是一款通用性很好的文件日志采集工具,解决工厂环境下,通过共享目录采集文件,SMB协议存在的安全性,兼容性的问题. 同时,我们发现工厂设备日志一般为增量,为方便MES,QMS等后端系统直接使用数据,我们推出了增量采…...
消息队列篇--原理篇--Pulsar(Namespace,BookKeeper,类似Kafka甚至更好的消息队列)
Apache Pulusar是一个分布式、多租户、高性能的发布/订阅(Pub/Sub)消息系统,最初由Yahoo开发并开源。它结合了Kafka和传统消息队列的优点,提供高吞吐量、低延迟、强一致性和可扩展的消息传递能力,适用于大规模分布式系…...
linux 扩容
tmpfs tmpfs 82M 0 82M 0% /run/user/1002 tmpfs tmpfs 82M 0 82M 0% /run/user/0 [输入命令]# fdisk -lu Disk /dev/vda: 40 GiB, 42949672960 bytes, 83886080 sectors Units: sectors of 1 * 512 512 bytes Sector size (logi…...
数据表中的数据查询
文章目录 一、概述二、简单查询1.列出表中所有字段2.“*”符号表示所有字段3.查询指定字段数据4.DISTINCT查询 三、IN查询四、BETWEEN ADN查询1.符合范围的数据记录查询2.不符合范围的数据记录查询 五、LIKE模糊查询六、对查询结果排序七、简单分组查询1.统计数量2.统计计算平均…...
深入了解 Java split() 方法:分割字符串的利器
Java 提供的 split() 方法是 String 类中一个常用的工具,它可以将一个字符串根据指定的分隔符切割成多个子字符串,并以字符串数组的形式返回。这个方法常用于字符串的处理、数据解析等场景。本文将详细介绍 Java 中 split() 方法的使用方式,并…...
Ubuntu 安装 docker 配置环境及其常用命令
Docker 安装与配置指南 本文介绍如何在 Ubuntu 系统上安装 Docker,解决权限问题,配置 Docker Compose,代理端口转发,容器内部代理问题等并进行相关的优化设置。参考官方文档:Docker 官方安装指南 一、安装 Docker 1…...
Android Studio安装配置
一、注意事项 想做安卓app和开发板通信,踩了大坑,Android 开发不是下载了就能直接开发的,对于新手需要注意的如下: 1、Android Studio版本,根据自己的Android Studio版本对应决定了你所兼容的AGP(Android…...
leetcode 面试经典 150 题:有效的括号
链接有效的括号题序号20题型字符串解法栈难度简单熟练度✅✅✅ 题目 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须…...
C语言 指针_野指针 指针运算
野指针: 概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的) 指针非法访问: int main() {int* p;//p没有初始化,就意味着没有明确的指向//一个局部变量不初始化,放…...
【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发之常见布局
目录 1 -> 自适应布局 1.1 -> 线性布局 1.1.1 -> 线性布局的排列 1.1.2 -> 自适应拉伸 1.1.3 -> 自适应缩放 1.1.4 -> 定位能力 1.1.5 -> 自适应延伸 1.2 -> 层叠布局 1.2.1 -> 对齐方式 1.2.2 -> Z序控制 1.3 -> 弹性布局 1.3.1…...
java基础学习——jdbc基础知识详细介绍
引言 数据的存储 我们在开发 java 程序时,数据都是存储在内存中的,属于临时存储,当程序停止或重启时,内存中的数据就会丢失,我们为了解决数据的长期存储问题,有以下解决方案: 通过 IO流书记&…...
第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
第十五届的题目在规定时间内做出了前5道,还有2道找时间再磨一磨。现在把做的一些思路总结如下: 题1:握手问题 问题描述 小蓝组织了一场算法交流会议,总共有 50人参加了本次会议。在会议上,大家进行了握手交流。按照惯例…...
基于JAVA的微信点餐小程序设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
2K320Hz显示器哪个好?
2K320Hz显示器哪个好?320Hz这种高刷新率的显示器确实很少见,那究竟哪个牌子哪个型号更适合你呢? 1.HKC G27H4Pro - 2K320Hz显示器哪个好 外观设计 - HKC G27H4Pro 2K320Hz显示器 三面微边框超震撼:采用三面微边框设计࿰…...
八股学习 微服务篇
微服务篇 常见面试内容Spring Cloud 常见组件注册中心Ribbon负载均衡策略服务雪崩 常见面试内容 Spring Cloud 常见组件 Spring Cloud有5个常见组件: Eureka/Nacos:注册中心;Ribbon:负载均衡;Feign:远程调用;Hystrix/Sentinel:服…...
C# 中 readonly 与 const 的使用
总目录 前言 在C#编程中,readonly 和 const 是两个用于定义不可变数据的关键字。它们都旨在创建那些一旦赋值后就不能再改变的字段或变量。尽管这两个关键字看起来相似,但它们有着不同的特性和适用场景。本文将深入探讨 readonly 和 const 的区别&#…...
Spring Boot Starter介绍
前言 大概10来年以前,当时springboot刚刚出现并没有流行,当时的Java开发者们开发Web应用主要是使用spring整合springmvc或者struts、iBatis、hibernate等开发框架来进行开发。项目里一般有许多xml文件配置,其中配置了很多项目中需要用到的Be…...
Kafak 单例生产者实现-C#操作
前面写了一篇入门操作的文章,因为工作需要,简单修改了下如何实现单例生产者。 Kafka入门-C#操作_c# kafka-CSDN博客文章浏览阅读1.6k次,点赞20次,收藏9次。2).报错:“kafka.zookeeper.ZooKeeperClientTimeoutException: Timed out waiting for connection while in state…...
软件开发学习路线——roadmap
推荐软件学习路线网站:https://roadmap.sh/get-started 有有关前端后端开发的学习路径,也有AI,移动开发,管理相关的学习路径 会有相应的词条路径,深入学习 右上角可以设置学习任务的完成情况...
移动端VR处理器和传统显卡的不同
骁龙 XR 系列芯片 更多地依赖 AI 技术 来优化渲染过程,而传统的 GPU 渲染 则倾向于在低画质下运行以减少负载。这种设计是为了在有限的硬件资源下(如移动端 XR 设备)实现高性能和低功耗的平衡。以下是具体的分析: 1. AI 驱动的渲染…...
Jenkins下载 Maven、Allure 插件并且配置环境
文章目录 Jenkins在插件中心下载 maven、allure插件maven插件下载allure插件下载 配置maven、allure 往期推荐: 最新! 在 Linux上搭建Jenkins环境! Jenkins邮件通知的详细配置含邮件通知模板! Jenkin配置企业微信通知 Jenkins在插件中心下载 maven、…...
C# OpenCV机器视觉:连通域分割
在一个阳光明媚得有些 “嚣张” 的午后,阿强像只好奇的小松鼠,一头扎进了他那乱得像被打劫过的实验室。这实验室里,各种电路板、奇形怪状的传感器和缠成一团的电线肆意横陈,仿佛在诉说着主人平日里为科研疯狂的 “战斗” 痕迹。阿…...
【嵌入式】总结——Linux驱动开发(三)
鸽了半年,几乎全忘了,幸亏前面还有两篇总结。出于快速体验嵌入式linux的目的,本篇与前两篇一样,重点在于使用、快速体验,uboot、linux、根文件系统不作深入理解,能用就行。 重新梳理一下脉络,本…...
python操作mysql
前言 在 Python3 中,我们可以使用mysqlclient或者pymysql三方库来接入 MySQL 数据库并实现数据持久化操作。二者的用法完全相同,只是导入的模块名不一样。我们推荐大家使用纯 Python 的三方库pymysql,因为它更容易安装成功。下面我们仍然以之…...