快慢指针算法是一种常用的技巧,用于解决链表中的问题。通常用于链表的遍历、查找等问题
1. 算法的思想
快慢指针算法的思想是:两个指针以不同的速度遍历链表,从而达到目的。其中,快指针每次移动两个节点,而慢指针每次移动一个节点。
2. 常见应用场景
快慢指针的常见应用场景有:
判断链表是否有环
寻找链表的中点
寻找链表的倒数第k个节点
寻找链表的交点
寻找链表的入环点
计算链表的环的长度‘
3. 具体实现
3.1 应用一 判断链表是否有环
使用双指针算法可以判断链表是否有环。具体来说,我们可以定义两个指针:一个慢指针和一个快指针。慢指针每次移动一步,而快指针每次移动两步。如果链表中有环,那么快指针最终会追上慢指针。如果没有环,那么快指针会到达链表的末尾。
以下是Java代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public boolean hasCycle(ListNode head) { if (head == null || head.next == null ) { return false ; } ListNode slow = head; ListNode fast = head.next; while (slow != fast) { if (fast == null || fast.next == null ) { return false ; } slow = slow.next; fast = fast.next.next; } return true ; } |
3.2 寻找链表的中点
使用双指针算法可以寻找链表的中点。具体来说,我们可以定义两个指针:一个慢指针和一个快指针。慢指针每次移动一步,而快指针每次移动两步。当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。
以下是Java代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 | public ListNode findMiddle(ListNode head) { if (head == null ) { return null ; } ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null ) { slow = slow.next; fast = fast.next.next; } return slow; } |
3.2 使用双指针算法可以寻找链表的倒数第k个节点
使用双指针算法可以寻找链表的倒数第k个节点。具体来说,我们可以定义两个指针:一个快指针和一个慢指针。快指针先走k步,然后慢指针开始走。当快指针到达链表末尾时,慢指针指向的节点即为链表的倒数第k个节点。
以下是Java代码示例:
public ListNode findKthToLast(ListNode head, int k) {
if (head == null || k <= 0) {
return null;
}
ListNode fast = head;
ListNode slow = head;
for (int i = 0; i < k; i++) {
if (fast == null) {
return null;
}
fast = fast.next;
}
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
3.3 寻找链表的交点
使用双指针算法可以寻找链表的交点。具体来说,我们可以定义两个指针:一个指向第一个链表的头节点,另一个指向第二个链表的头节点。然后,我们同时遍历两个链表,如果两个指针指向的节点相同,则它们相交。如果两个链表长度不同,则我们可以让较长的链表的指针先走若干步,然后再同时遍历两个链表。
以下是Java代码示例:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode pA = headA;
ListNode pB = headB;
while (pA != pB) {
pA = (pA == null) ? headB : pA.next;
pB = (pB == null) ? headA : pB.next;
}
return pA;
}
3.4使用双指针算法可以计算链表的环的长度
使用双指针算法可以计算链表的环的长度。具体来说,我们可以定义两个指针:一个指向链表的头节点,另一个指向链表的头节点。然后,我们同时遍历链表,如果两个指针指向的节点相同,则它们相交。如果链表中存在环,则我们可以让其中一个指针指向链表头,另一个指针处于原位置不动,一人一步地走,直到它们再次相遇。此时,它们所走过的距离即为环的长度。
以下是Java代码示例:
public int getLoopLength(ListNode head) {
if (head == null) {
return 0;
}
ListNode slow = head;
ListNode fast = head;
boolean hasLoop = false;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
hasLoop = true;
break;
}
}
if (!hasLoop) {
return 0;
}
int length = 1;
slow = slow.next;
while (slow != fast) {
slow = slow.next;
length++;
}
return length;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2019-03-28 tomcat -web.xml里的内容
2019-03-28 tcp协议和udp协议的使用场景