美文网首页
链表骚操作 --- 快慢指针

链表骚操作 --- 快慢指针

作者: 贪挽懒月 | 来源:发表于2020-09-17 18:04 被阅读0次

快慢指针,顾名思义,就是操作链表的时候,使用两个指针,一快一慢。灵活使用快慢指针,可以巧妙的解决很多问题。本文将介绍如下问题:

  • 找到链表中的倒数第K个节点(leetCode 剑指offer22);
  • 找到链表的中点;
  • 删除链表倒数第K个节点;
  • 判断链表是否有环

先定义一个链表类:

public class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
    }
}

欢迎大家关注我的公众号 javawebkf,目前正在慢慢地将简书文章搬到公众号,以后简书和公众号文章将同步更新,且简书上的付费文章在公众号上将免费。


一、找到链表的倒数第K个节点

1. 题目描述:

假如现有如下链表,且k = 2

1 --> 2 --> 3 --> 4 --> 5 --> 6

那么则应输出(倒数第K个节点,而不是倒数第K个节点的值):

5 --> 6

2. 题目分析:

  • 定义两个指针,一个fast,一个slow,一开始都在第一个位置;
  • 假设链表长度为n,倒数第k个,那么就是顺数第n-k+1个,需要移动的步数就是n-k
  • fast先走k步,此时fast离链表尾就还有n-k步;
  • 然后让slowfast同时向后移动,当fast移动到最后的时候,slow就移动了n-k步,就找到了目标节点。

3. 代码实现:

public ListNode getKthFromEnd(ListNode head, int k) {
    ListNode fast = head;
    ListNode slow = head;
    for(int i=0; i<k; i++) {
        fast = fast.next;
    }
    while(fast != null) {
        fast = fast.next;
        slow = slow.next;
    }
    return slow;
}

二、找到链表的中点

1. 题目描述:

输入链表:

1 --> 2 --> 3 --> 4 --> 5 --> 6

则应输出:

4 --> 5 --> 6

输入:

1 --> 2 --> 3 --> 4 --> 5

输出:

3 --> 4 --> 5

2. 题目分析:

  • 定义两个指针,一个fast,一个slow,一开始都在第一个位置;
  • 然后同时移动两个指针,让fastslow快一倍,当fast到尾了,slow就刚好在中点。

3. 代码实现:

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

三、删除链表倒数第K个节点

1. 题目描述:

输入如下链表,且k = 2

1 --> 2 --> 3 --> 4 --> 5 --> 6

输出:

1 --> 2 --> 3 --> 4 --> 6

2. 题目分析:

  • 定义两个指针,一个fast,一个slow,一开始都在第一个位置;
  • 要删除倒数第k个节点,就要找到它的前一个节点,即倒数第k+1个节点,顺数就是(n-k-1)
  • 所以让fastk+1步,等fast到尾的时候,slow就在(n-k-1)的位置。

3. 代码实现:

public ListNode delFromEnd(ListNode head, int k) {
    ListNode fast = head;
    ListNode slow = head;
    // 让fast比slow快k步
    for(int i=0; i<k+1; i++) {
        fast = fast.next;
    }
    // 将slow移到倒数k+1位置,经过该步骤,slow指向要删除节点的前一个节点
    while(fast != null) {
        fast = fast.next;
        slow = slow.next;
    }
    // 这里让前一个节点的next等于要删除节点的next,就将要删除的节点删除了
    slow.next = slow.next.next;
    return head;
}

四、判断链表是否有环

1. 题目描述:

如果输入的是环形链表,则输出true,反之输出false。

2. 题目分析:

两个人在环形跑道上跑步,从同一起点出发,一个人速度快,一个人速度慢,不管他们的速度相差多少,只要是有速度差,他们总有再次相遇的时刻。所以,我们可以使用快慢指针,判断链表是否有环。如果两个指针会再次相遇,就是有环,反之无。

3. 代码实现:

public boolean hasCircle(ListNode head) {
    ListNode fast = head;
    ListNode slow = head;
    while(fast != null && fast.next != null) {
        fast = fast.next.next;
        slow = slow.next;
        if (fast == slow) {
            return true;
        }
    }
    return false;
}

怎么样,关于快慢指针,大家学废了吗

相关文章

  • 链表骚操作 --- 快慢指针

    快慢指针,顾名思义,就是操作链表的时候,使用两个指针,一快一慢。灵活使用快慢指针,可以巧妙的解决很多问题。本文将介...

  • 快慢指针的应用

    什么是快慢指针:快慢指针是链表操作中的常用操作,最经典的应用是判断单链表中是否有环。 判断单链表是否存在环 两个指...

  • 算法学习--双指针

    双指针分类 快慢指针 左右指针 快慢指针:主要解决链表相关问题,比如:典型的判断链表中是否包含环、链表倒是第K个节...

  • 快慢指针的应用

    快慢指针的快慢主要是指在遍历链表过程中指针移动速度的快慢。比如遍历单链表,我们可以让指针每次移动一个节点,也可以让...

  • Tourist with Data Structure Seco

    链表 读题要仔细,只看题干,容易死的很惨。 设计链表 环形链表 一般环形链表使用快慢指针方式去做,快慢指针算法。参...

  • leetcode第142题:环形链表II [中等]

    题目描述 考点 链表 双指针(快慢指针) 解题思路 设置快慢指针slow, fast; 慢指针slow每次移动一个...

  • 单向链表

    参考我的博客 单向链表(LinkedList) 链表 链表二级指针的骚操作配合Debug观察内存状况更加容易学习!...

  • 快慢指针-链表

    实际上,双指针是一个很笼统的概念。只要在解题时用到了两个指针(链表指针、数组下标皆可),都可以叫做双指针方法。根据...

  • leetcode刷题-链表

    链表题目汇总: 主要是发现 206 141环形链表(快慢指针) 21写递归 19 876 快慢指针,一个走2步,一...

  • 纯C手撕leetcode-基本数据结构-链表

    技巧 假头 新链表 双指针(正反向指针,快慢指针) 递归 例子:1.合并两个有序链表(假头,新链表) 链表反转(假...

网友评论

      本文标题:链表骚操作 --- 快慢指针

      本文链接:https://www.haomeiwen.com/subject/dcflyktx.html