继续打卡算法题,今天学习的是LeetCode的19题删除链表的倒数第N个结点,这道题目是道中等题。算法题的一些解题思路和技巧真的非常巧妙,每天看一看算法题和解题思路,我相信对我们的编码思维和编码能力有一些帮助。
分析一波题目
这道题目比较有技巧性,单链表有个关键特性是只能从头到尾进行遍历的
。如果我们使用死办法,我们肯定需要遍历两次链表,第一次遍历判断链表的长度,第二层遍历到倒数第n个节点前,移出倒数第n个节点。
在数组里里面,通过双指针可以减少循环次数,在链表中,我们也可以使用快慢双指针减少遍历链表次数。
我们只要有两个指针,一个指针是倒数第n个指针的前一个指针,一个指针是最后一个节点,这两个指针分别叫做慢,快指针
,这个时候就非常容易对倒数第n个节点进行删除了。
我们怎么可以得到这两个指针呢?这就是解决本题的关键了。
我们只要将一个快指针先n步,然后慢指针和快指针一起从头开始遍历,直到快指针先到达链尾。
比如需要删除倒数第2个节点,快慢指针初始状态如下:
快慢指针一起遍历,直达快指针的next节点为空时
这个时候只要把慢指针指向 慢指针的next.next
节点就可以了。
编码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//设置虚拟节点,并指向头几点
ListNode dumy = new ListNode(0);
dumy.next = head;
ListNode fastNode = dumy;
ListNode slowNode = dumy;
for(int i=0; i<n; i++) {
fastNode = fastNode.next;
}
while(fastNode.next != null) {
fastNode = fastNode.next;
slowNode = slowNode.next;
}
slowNode.next = slowNode.next.next;
return dumy.next;
}
}
总结
快慢指针可以减少循环数组的次数,在单链表的遍历过程中使用快慢双指针也可以减少遍历的次数。