19. 删除链表的倒数第N个节点
2022-10-08 本文已影响0人
一直流浪
19. 删除链表的倒数第N个节点
题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/submissions/
难度:中等
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
解法一:暴力法(需要遍历两次)
遍历链表,计算出链表长度len,然后计算出需要删除的结点的下标位置tag = len - n;
再遍历链表,让需要删除的结点的上一个结点的next指向需删除结点的next结点。
复杂度分析
时间复杂度:O(L),该算法对列表进行了两次遍历,首先计算了列表的长度 L其次找到第 (L - n) 个结点。 操作执行了 2L-n 步,时间复杂度为 O(L)。
空间复杂度:O(1),我们只用了常量级的额外空间。
`
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
int len = 1;
if(head == null) {
return null;
}
ListNode node = head;
while(node.next!=null) {
len ++;
node = node.next;
}
node = head;
int tag = len - n;
if(tag == 0) {
return head.next;
}
while(node.next!=null) {
tag--;
if(tag == 0) {
node.next = node.next.next;
break;
}
node = node.next;
}
return head;
}
}
`
解法二:双指针法(只要一次遍历)
我们可以使用两个指针L和R来遍历数组 , 先让两个结点的距离相聚n-1 , 起初让两个指针都指向头结点 , 然后先让R指针向后移动 n-1个结点。然后同时移动两个指针,当R指针移动到最后一个的时候,L指针指向的刚好是需要删点的结点。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode R = dummy;
ListNode L = dummy;
for(int i = 0;i<n+1;i++) {
R = R.next;
}
while(R!=null) {
R = R.next;
L = L.next;
}
L.next = L.next.next;
return dummy.next;
}
}