LeetCode第19题思悟——删除链表的倒数第N个节点(remove-nth-node-from-end-of-list)

LeetCode第19题思悟——删除链表的倒数第N个节点(remove-nth-node-from-end-of-list)

知识点预告

  1. 双指针遍历技巧得以扩展:同向同速双指针遍历;
  2. 思考问题的模式:归纳【尾节点(倒数第一个节点)和倒数第N个节点之间的关系】和演绎【倒数第N个-正数第K个-链表长度】

题目要求

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

给定的 n 保证是有效的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

示例

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的思路

一般解法是首先求出链表的长度,然后计算出倒数第N个节点的正序数字,接着就是链表删除的常规操作;这种思路的形成过程为:

  1. 删除节点,首先得定位节点;
  2. 倒数第N个节点可通过计算得到正数情况下的编号;
  3. 要知道正数情况下的编号,需要链表长度;

于是操作顺序就变成了:首先获取链表长度,然后计算得出正数数字,接着删除;

这里的第2步是可以优化的;我们是需要定位节点,但是我们不一定需要通过计算来得到;

在链表中,我们很容易得到的是尾节点和头节点以及正数的第N个节点,这是因为尾节点的next指向null;那么我们如何通过尾节点得到倒数第N个节点呢?于是我们需要在该节点与尾节点之间建立联系:它们的正数顺序相差N-1(倒数第N减去倒数第1);

也即是说,当指针P指向尾节点时,指针S指向倒数第N个节点,S与P相差N-1;那么当S指向头节点的时候,P便指向正数第N个节点;于是第2种解法就产生了:

public ListNode removeNthFromEnd(ListNode head, int n) {
	ListNode fastPointer=head;
	ListNode slowPointer=head;
	for(int i=0;i<n;i++){
		fastPointer=fastPointer.next;
	}
	if(fastPointer==null){//删除的是头结点
		return head.next;
	}
	while(fastPointer.next!=null){
		fastPointer=fastPointer.next;
		slowPointer=slowPointer.next;
	}
	slowPointer.next=slowPointer.next.next;
	return head;
}

优秀解法

//解法A
public ListNode removeNthFromEnd(ListNode head, int n) {
	ListNode tempNode = head;
	int length = getLength(tempNode);
	if (length==n) {
		head = head.next;
		return head;
	}
	for (int i = 1; i <= length; i++) {
		if (i == length - n) {
			tempNode.next = tempNode.next.next;
			break;
		}
		tempNode = tempNode.next;
	}
	return head;
}
public int getLength(ListNode head) {
	int result = 1;
	while (head.next != null) {
		head = head.next;
		result++;
	}
	return result;
}

差异分析

我们来分析两种解法的效率:

自己的解法里,快指针遍历了一遍链表(移动L-1次);慢指针经过了L-N+1个节点(移动了L-N次);所以对于N,我们的解法共移动指针:L-1+L-N=2L-1-N次;无额外计算;

优秀解法里:同样分析,移动指针2L-1-N次,但是为了计算长度,是有自增操作的;从理论上分析,自己的解法应该操作次数更少;

知识点小结

  1. 双指针遍历技巧得以扩展:同向同速双指针遍历;
  2. 思考问题的模式:归纳【尾节点(倒数第一个节点)和倒数第N个节点之间的关系】和演绎【倒数第N个-正数第K个-链表长度】
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值