0


我有一式算法绝学,名曰‘快慢指针’

从下面三个问题综合展示和应用

快慢指针

快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2,慢指针每次向前移动1次。
  1. 判断单链表是否为循环链表
  2. 在有序链表中寻找中位数

这三个分别为:

141. 环形链表

142. 环形链表 II

143. 重排链表

,三个问题我们一个一个来说,并且将其中的一道题目从朴素解法到

快慢指针

转化。

1. 141. 环形链表

https://leetcode-cn.com/problems/linked-list-cycle/

1.1. 题目描述

在这里插入图片描述

1.2. 解题代码

1.2.1. 基本解法

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public bool HasCycle(ListNode head) {
        List<ListNode> listDicCache=new List<ListNode>();
        while(head!=null)
        {
            if(listDicCache.Contains(head))
            {
                return true;
            }
            else
            {
                listDicCache.Add(head);
                head=head.next;
            }
        }
        return false;
    }
}

在这里插入图片描述

1.2.2. 字典基本解法

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public bool HasCycle(ListNode head) {
        Dictionary<ListNode,bool> dicCache=new Dictionary<ListNode, bool>();
        while(head!=null)
        {
            if(dicCache.ContainsKey(head))
            {
                return true;
            }
            else
            {
                dicCache.Add(head,true);
                head=head.next;
            }
        }
        return false;
    }
}

在这里插入图片描述

1.2.3. 快慢指针解法

假想「乌龟」和「兔子」在链表上移动,
「兔子」跑得快,「乌龟」跑得慢。
当「乌龟」和「兔子」从链表上的同一个节点开始移动时,
如果该链表中没有环,那么「兔子」将一直处于「乌龟」的前方;
如果该链表中有环,那么「兔子」会先于「乌龟」进入环,
并且一直在环内移动。
等到「乌龟」进入环时,由于「兔子」的速度快,它一定会在某个时刻与乌龟相遇,即套了「乌龟」若干圈。

我们可以根据上述思路来解决本题。
具体地,我们定义两个指针,一快一满。
慢指针每次只移动一步,而快指针每次移动两步。
初始时,慢指针在位置 head,而快指针在位置 head.next。
这样一来,如果在移动的过程中,快指针反过来追上慢指针,
就说明该链表为环形链表。否则快指针将到达链表尾部,该链表不为环形链表。

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public bool HasCycle(ListNode head) {

        ListNode slowNode=head;
        ListNode fastNode=head;
        while(fastNode!=null&&fastNode.next!=null)
        {
            fastNode=fastNode.next.next;

            if(slowNode==fastNode)   
            {
                return true;
            }
            slowNode=slowNode.next;
        }
        return false;
    }
}

在这里插入图片描述

2. 142. 环形链表 II

https://leetcode-cn.com/problems/linked-list-cycle-ii/

2.1. 题目描述

在这里插入图片描述

2.2. 解题代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode DetectCycle(ListNode head) {
        ListNode slowNode=head;
        ListNode preNode=head;
        ListNode fastNode=head;

        while(fastNode!=null&& fastNode.next!=null)
        {
            slowNode=slowNode.next;
            fastNode=fastNode.next.next;
            if(slowNode==fastNode)
            {
                while(preNode!=slowNode)
                {
                    preNode=preNode.next;
                    slowNode=slowNode.next;
                }
                return preNode;
            }
        }
        return null;
    }
}

解题思路:

实在使用电脑太难绘制了 只能贴一下草稿纸

在这里插入图片描述

在这里插入图片描述

3. 143. 重排链表

https://leetcode-cn.com/problems/reorder-list/

3.1. 题目描述

在这里插入图片描述

2.2. 解题代码

2.2.1 List朴素解法

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int val=0, ListNode next=null) {
 *         this.val = val;
 *         this.next = next;
 *     }
 * }
 */
public class Solution {
    public void ReorderList(ListNode head) {
        if (head == null) {
            return;
        }
        List<ListNode> list=new List<ListNode>();
        ListNode node = head;
        while (node != null) {
            list.Add(node);
            node = node.next;
        }
        int i = 0, j = list.Count - 1;
        while (i < j) {
            list[i].next = list[j];
            i++;
            if (i == j) {
                break;
            }
            list[j].next = list[i];
            j--;
        }
        list[i].next = null;
    }
}

在这里插入图片描述

2.2.2 快慢指针解法

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int val=0, ListNode next=null) {
 *         this.val = val;
 *         this.next = next;
 *     }
 * }
 */
public class Solution {
    public void ReorderList(ListNode head) {
        if (head == null) {
            return;
        }
        ListNode mid = MiddleNode(head);
        ListNode l1 = head;
        ListNode l2 = mid.next;
        mid.next = null;
        l2 = ReverseList(l2);
        MergeList(l1, l2);
    }

    public ListNode MiddleNode(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }

    public ListNode ReverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode nextTemp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }

    public void MergeList(ListNode l1, ListNode l2) {
        ListNode l1_tmp;
        ListNode l2_tmp;
        while (l1 != null && l2 != null) {
            l1_tmp = l1.next;
            l2_tmp = l2.next;

            l1.next = l2;
            l1 = l1_tmp;

            l2.next = l1;
            l2 = l2_tmp;
        }
    }
}

在这里插入图片描述

标签: leetcode

本文转载自: https://blog.csdn.net/a13407142317/article/details/124303852
版权归原作者 自己的九又四分之三站台 所有, 如有侵权,请联系我们删除。

“我有一式算法绝学,名曰&lsquo;快慢指针&rsquo;”的评论:

还没有评论