19. Remove Nth Node From End of List & 快慢指针

来源:互联网 发布:linux虚拟机桥接上网 编辑:程序博客网 时间:2024/06/05 20:48

定义:

       快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2,慢指针每次向前移动1次。

 

应用:

1、判断链表是否为循环链表:

让快慢指针从链表头开始遍历,快指针向前移动两个位置,慢指针向前移动一个位置;如果快指针到达NULL,说明链表以NULL为结尾,不是循环链表。如果快指针追上慢指针,则表示出现了循环。  

 

2、在有序列表中寻找中位数         

该方法在不借助计数器变量实现寻找中位数的功能。

原理是:

快指针的移动速度是慢指针移动速度的2倍,因此当快指针到达链表尾时,慢指针到达中点。程序还要考虑链表结点个数的奇偶数因素。当快指针移动x次后到达表尾(1+2x),说明链表有奇数个结点,直接返回慢指针指向的数据即可。如果快指针是倒数第二个结点,说明链表结点个数是偶数,这时可以根据规则返回上中位数或下中位数或(上中位数+下中位数)的一半。

 

3、如果链表为存在环,如果找到环的入口点

fast若与slow相遇时,slow肯定没有走遍历完链表(不是一整个环,有开头部分,如上图)或者恰好遍历一圈。于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点(慢指针走了n步,第一次相遇在c点,对慢指针来说n=s+p,也就是说如果慢指针从c点再走n步,又会到c点,那么顺时针的CB距离是n-p=s,但是我们不知道s是几,那么当快指针此时在A点一步一步走,当快慢指针相遇时,相遇点恰好是圆环七点B(AB=CB=s))

 

3、判断两个单链表是否相交,如果相交,给出相交的第一个点(两个链表都不存在环)

单链表相交(两个链表都不存在环),链表结束必定都是相同的节点

1.将其中一个链表首尾相连,检测另外一个链表是否存在环,如果存在,则两个链表相交,而检测出来的依赖环入口即为相交的第一个点。
  2.如果两个链表相交,那个两个链表从相交点到链表结束都是相同的节点,我们可以先遍历一个链表,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交。这时我们记下两个链表length,再遍历一次,长链表节点先出发前进(lengthMax-lengthMin)步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。

 

最后

指针可以相差k倍数,那也可以相差k位啦,比如求链表的倒数第n位。即本题解法

 

Given a linkedlist, remove the nth node fromthe end of list and return its head.

For example,

  Given linked list: 1->2->3->4->5, andn = 2.

 

  After removing the second node from the end, the linked list becomes1->2->3->5.

Note:
Given n will always be valid.
Try to do this in one pass.

常规思路:遍历两次,第一次计算链表元素数,第二次修改;

public class Solution {    public ListNode removeNthFromEnd(ListNode head, int n) {               ListNode tmp = head;        int tol = 1;        while(tmp.next != null){            tmp = tmp.next;            tol++;        }        tmp = head;               int j = tol - n;        if(j == 0)            return head.next;        for(int i=1;i<j;i++){            tmp = tmp.next;        }        tmp.next = tmp.next.next;        return head;    }}


快慢指针思路:当n<=0时,慢指针才开始移动

 

public class Solution {    public ListNode removeNthFromEnd(ListNode head, int n) {               ListNode headNode = new ListNode(1);        headNode.next = head;        ListNode fastNode = headNode;        ListNode slowNode = headNode;               while(fastNode.next != null){            if(n <= 0)                slowNode = slowNode.next;            fastNode = fastNode.next;            n--;        }        if(slowNode.next != null)            slowNode.next = slowNode.next.next;        return headNode.next;    }}

  

0 0