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个节点

给定一个链表,删除链表的倒数第 个节点,并且返回链表的头结点。

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;
    }
}

 

posted @ 2018-12-11 17:32  田错  阅读(745)  评论(0编辑  收藏  举报