难度中等1504收藏分享切换为英文接收动态反馈
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
示例 1:
输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1 输出:[]
示例 3:
输入:head = [1,2], n = 1 输出:[1]
提示:
- 链表中结点的数目为
sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
思路:
1.第一想法,遍历两边,获取长度删除节点。
2.看到进阶,需要一次完成,经过思考可以使用后序遍历解决问题。
3.通过双指针实现,第二根指针提前n步,循环到底则第一根指针是需要删除的节点,但是要找到前驱节点所以要提前n+1步
4.可以使用堆栈来解题。
代码实现:本人代码是通过递归实现,首先在遍历时计算长度,用于头节点的判断,后续遍历计算倒数计数,找到需要删除节点的前驱节点,删除节点后返回。判断链表长度是否等于需要删除的倒数计数,如果相等则删除头节点。具体代码如下:
public class question_19 {
/**
* 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; }
* }
*/
//定义倒数计数
int nn = 0;
//定义长度
int len = 0;
public ListNode removeNthFromEnd(ListNode head, int n) {
if(head==null || head.next==null) {
return null;
}
//获取倒数个数
nn = n;
dp(head);
//如果链表长度等于n 则删除头节点
if(len == nn) {
return head.next;
}
return head;
}
public int dp(ListNode node) {
if(node==null) {
return 1;
}
//计算长度
len++;
int i = dp(node.next);
//判断是否是需要删除节点的前驱节点
if(i-1 == nn) {
node.next = node.next.next;
}
//返回节点倒数计数
return ++i;
}
public static void main(String[] args) {
ListNode head = new ListNode(1);
head.next = new ListNode(2);
// head.next.next = new ListNode(3);
// head.next.next.next = new ListNode(4);
// head.next.next.next.next = new ListNode(5);
question_19 question_19 = new question_19();
head = question_19.removeNthFromEnd(head, 2);
System.out.println(head.toString());
}
}
class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}