前言
“这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战”
总结下链表结合双指针的问题
- NC69 链表中倒数最后k个结点(中等)
- NC53 删除链表的倒数第n个节点(中等)
链表中倒数最后k个结点
描述: 输入一个链表,输出一个链表,该输出链表包含原链表中从倒数第k个结点至尾节点的全部节点。
如果该链表长度小于k,请返回一个长度为 0 的链表。
思路分析:
- 遍历一遍链表统计节点数, 找到index 为 len - k 的节点(index 从 0 开始), 注意 k > len 直接返回 空链表
- 双指针,fast 指针先走 k步, 然后 slow 指针 指向头节点, fast 和 slow 一起向后移动 直到 fast 为 null 时, slow 指向的就是倒数第 k 个节点
AC 代码:
遍历版本:
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
if(pHead == null) return null;
int count = 1;
ListNode cur = pHead;
while(cur.next != null){
count++;
cur = cur.next;
}
if(k > count) return null;
int index = count - k;
int i = 0;
cur = pHead;
while(i != index){
cur = cur.next;
i++;
}
return cur;
}
双指针版本:
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
if(pHead == null) return null;
ListNode slow = pHead;
ListNode fast = pHead;
while(k != 0){
if(fast == null){
return null;
}
fast = fast.next;
k--;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
删除链表的倒数第n个节点
描述:给定一个链表,删除链表的倒数第 n 个节点并返回链表的头指针 例如,
给出的链表为:1→2→3→4→5, n=2 删除了链表的倒数第 n 个节点之后,链表变为 1→2→3→5.
备注:题目保证 n 一定是有效的
思路分析: 整体上思路和上一道题一样, 利用双指针找到倒数第 k 个节点, 不同的是这个需要删除倒数第k个节点,因此需要知道倒数第 k个节点的前置节点, 因为删除的可能是头节点,所以添加一个虚拟的头节点(pre),fast 指针先走 k步,pre 和 fast 一起向后移动, 当 fast 为空时, pre 指向的正是 倒数第k个节点的前置节点
AC代码:
public ListNode removeNthFromEnd (ListNode head, int n) {
// write code here
ListNode pre = new ListNode(-1);
pre.next = head;
ListNode ans = pre;
ListNode fast = head;
while(n != 0){
fast = fast.next;
n--;
}
while(fast != null){
fast = fast.next;
pre = pre.next;
}
pre.next = pre.next.next;
return ans.next;
}