LeetCode-探索链表-双指针技巧
环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。
如果 pos
是 -1
,则在该链表中没有环。
public class Solution { public bool HasCycle(ListNode head) { //快慢指针检测单链表中是否存在环 if(head == null||head.next == null)return false; //快指针一次前进n倍慢指针的步数 ListNode fastNode=head.next; ListNode slowNode=head; //如果存在环,二者一定会碰上,得到相等的情况 while(fastNode!=slowNode){ if(fastNode == null||fastNode.next == null) return false; fastNode = fastNode.next.next; slowNode = slowNode.next; } return true; } }
环形链表 II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。
如果 pos
是 -1
,则在该链表中没有环。不允许修改给定的链表。
public class Solution { public ListNode DetectCycle(ListNode head) { if(head == null)return null; //fast步进2,slow,newNode步进1 ListNode fast=head,slow=head,newNode=head; bool hasCycle=false;//是否有环 //判断环的循环 while(fast.next != null&&fast.next.next != null){ fast = fast.next.next; slow = slow.next; if(fast==slow) { hasCycle=true; break; } } if(!hasCycle)return null; //判断环入口的循环 while(slow!=newNode){ slow = slow.next; newNode = newNode.next; } return newNode; } }
相交链表
编写一个程序,找到两个单链表相交的起始节点。
public class Solution { public ListNode GetIntersectionNode(ListNode headA, ListNode headB) { if(headA==null||headB==null)return null; ListNode na=headA,nb=headB; while(na!=nb){ na=na==null?headB:na.next;//na走A链表到头后从B链表head开始继续走 nb=nb==null?headA:nb.next;//nb走A链表到头后从A链表head开始继续走 } return na;//na/nb等于AB链表相交节点,AB链表不相交则为null } }
删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
public class Solution { public ListNode RemoveNthFromEnd(ListNode head, int n) { ListNode zero=new ListNode(0); zero.next=head; ListNode fast=zero; ListNode slow=zero; //将快指针放向前移动n次 for(int i=1;i<=n+1;i++) fast=fast.next; //循环遍历链表直到快指针到达尾部 while(fast!=null){ fast=fast.next; slow=slow.next; }//此时slow的后继结点为要删除的倒数第n个结点 slow.next=slow.next.next; return zero.next; } }