19.删除链表倒数第N个节点

题目描述

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

  • 示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:给定的 n 保证是有效的。

单链表定义如下:

	/**
	* public class ListNode {
	* int val;
	* ListNode next;
	* ListNode(int x) { val = x; }
	* }
	*/

解法一:
遍历整个链表,获得链表的长度。例如链表为1->2->3->4->5,n=2。当我们遍历遍一遍链表后,长度为5。n=2,所以我们要删除的节点为总长度减去n位置的节点+1,如果要删除节点p,则需要找到其前驱节点q,另q.next = p.next即可。
代码如下:

public ListNode removeNthFromEnd(ListNode head, int n) {        
	 ListNode p = head;         
	 int len = 0; 
	 //获取链表的长度        
	 while(p!=null){             
	 	len++;             
	 	p=p.next;         
	 }       
	 //如果要删除第一个节点 
	 if(n==len)             
	 	return head.next;         
	 len = len - n ;         
	 	p = head;        
	 //寻找要删除节点的前驱节点 
	 while(len > 1){             
	 	p=p.next;             
	 	len--;         
	 }         
	 //删除节点
	 p.next = p.next.next;        
	 return head;     
} 

解法二:
类似于快慢指针,不同的是不是移动速度的不同,而是初始位置的不同。如果要删除第n个节点,那么指针q从头节点向后移动n个节点的位置,然后p指针从头节点开始,p,q同时向后移动,当q为null时,p恰好在要删除的节点位置。
代码如下:


public ListNode removeNthFromEnd(ListNode head, int n) {
	ListNode p,q;
	p = q = head;
	while(n > 0){
		q = q.next;
		n--;
	}
	if(q==null){
	//如果只有一个节点
	if(p.next==null)
		return null;
	//如果有多个节点,且要删除的节点为第一个
	head = head.next;
	return head;
}
	//找到要删除节点的前驱节点,所以这里为q.next而不是q
	while(q.next !=null){
		p = p.next;
		q = q.next;
	}
		p.next = p.next.next;
		return head;
}

该解法与第一种相比,只需要遍历一遍链表即可。

你可能感兴趣的:(算法,LeetCode,删除链表倒数第N个节点)