给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
我的想法:因为是倒数第n个,所以最直观的想法就是求出这个链表的长度length,然后就变成了删除第length-n+1个,但是我这个方法需要记录两次头指针,比较占内存
代码如下:
/**
* 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) {
int length = 0;
ListNode first = new ListNode();
ListNode result = new ListNode();
first = head;
result = first;
while (head != null){
length++;
head = head.next;
}
if(length == 1){
return null;
}
if(length == n){
first = first.next;
return first;
}else{
ListNode delete = new ListNode();
ListNode pre = new ListNode();
for (int i = 0; i < length - n - 1; i++) {
first = first.next;
}
pre = first;
delete = pre.next;
pre.next = delete.next;
return result;
}
}
}
官方采用了快慢指针的思想:
由于我们需要找到倒数第 nn 个节点,因此我们可以使用两个指针 \textit{first}first 和 \textit{second}second 同时对链表进行遍历,并且 \textit{first}first 比 \textit{second}second 超前 nn 个节点。当 \textit{first}first 遍历到链表的末尾时,\textit{second}second 就恰好处于倒数第 nn 个节点。
代码如下:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
ListNode first = head;
ListNode second = dummy;
for (int i = 0; i < n; ++i) {
first = first.next;
}
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
ListNode ans = dummy.next;
return ans;
}
}