刷题模板 | 链表相关

1. 链表中有环:

快慢指针,一个每次两步,一个一步,最后相遇,就一定有环。

public boolean hasCycle(ListNode head) {
        if (head == null) return false;

        ListNode slow = head;
        ListNode fast = head;

        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;

            if (fast == slow) {
                return true;
            }
        }

        return false;
    }
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.next != null && fast.next.next != null) {
                fast = fast.next.next;
                slow = slow.next;
            }
            else {
                return false;
            }
        }
        return true;
}

2. 找到环的入口(剑指55)

1) 两个指针,一个从链表头开始,另一个从相遇点开始,每次都走一步,最后一定在环入口相遇。 

public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if (pHead == null || pHead.next == null || pHead.next.next == null) {
            return null;
        }

        ListNode fast = pHead.next.next;
        ListNode slow = pHead.next;

//        判断有没有环
        while (fast != slow) {
            if (fast.next != null && fast.next.next != null) {
                fast = fast.next.next;
                slow = slow.next;
            }
            else {
                return null;
            }
        }
//      此时fast==slow,就是相遇点
        fast = pHead;
        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }

        return slow;
    }

2)如果链表中 有n个结点,指针P1在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向环的入口结点时,第一个指针已经围绕着环走了一圈又回到了入口结点。

重点就是:如何找到环的长度

public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if (pHead == null || pHead.next == null || pHead.next.next == null) {
            return null;
        }

        ListNode fast = pHead.next.next;
        ListNode slow = pHead.next;

        while (fast != slow) {
            if (fast.next != null && fast.next.next != null) {
                fast = fast.next.next;
                slow = slow.next;
            }
            else {
                return null;
            }
        }

//        环的长度
        int loopLen = 1;
        while (slow.next != fast) {
            slow = slow.next;
            loopLen++;
        }

        fast = slow = pHead;
        int i = 0;
        while (i < loopLen) {
            fast = fast.next;
            i++;
        }

        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }

        return slow;
    }

3. 删除链表中重复节点(剑指56)

发布了53 篇原创文章 · 获赞 5 · 访问量 1517

猜你喜欢

转载自blog.csdn.net/zhicheshu4749/article/details/103861148
今日推荐