这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战
双指针巩固训练的第四天
删除链表的倒数第N个节点
该题出自力扣的19题 —— 删除链表的倒数第N个节点【中等题】
审题
给你一个链表,删除链表的倒数第
n个结点,并且返回链表的头结点。 例:
输入: head = [1,2,3,4,5], n = 2
输出: [1,2,3,5]
- 根据题意,一个链表删除相应的倒数节点。
- 因为是链表结构,所以遍历的缺陷会被无限放大。
- 解决方法:
- 计算链表长度 + List集合
- 遍历链表,并且存进List中
- 对指定的节点删除 = 对指定节点的上一节点的next指向下下节点
- 双指针
- 可以利用双指针的快慢指针
- 两个指针分别指向链表,相差N个节点同时启动,最终快指针到达终点,慢指针则为指定删除节点
- 计算链表长度 + List集合
编码
public ListNode removeNthFromEnd(ListNode head, int n) {
//删除 n = 修改 n - 1 的next
List<ListNode> listNodes = new ArrayList<>();
while (head != null){
listNodes.add(head);
head = head.next;
}
int len = listNodes.size();
int result = len - n;
if (result >0){
listNodes.get(result - 1).next = listNodes.get(result).next;
return listNodes.get(0);
}else if (result == 0 && len -1> 0){
return listNodes.get(1);
}else {
return null;
}
}
链表的中间节点
该题出自力扣的876题 —— 链表的中间节点
审题
给定一个头结点为
head的非空单链表,返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。
- 题意很简单,返回一个链表的中间节点开始的链表
- 利用双指针的快慢指针实现
- 两个指针同时指向链表
- 快指针每次移动两位,慢指针每次移动1位
- 最终快指针走到终点,慢指针就会走到一半
编码
public ListNode middleNode(ListNode head) {
ListNode p =head,q=head;
while(q != null && q.next != null){
q = q.next.next;
p = p.next;
}
return p;
}
总结
双指针的日常刷题还是较为常见的,但是也存在明显缺陷,集合需要有序。相比暴力循环,能够优化时间复杂度。