【LeetCode】详解删除链表的倒数第N个节点19. Remove Nth Node From End of ListGiven a linked list, remove the n-th
文章目录
前言
一开始我以为今天这道题很简单,也很快通过了,但是看了一下讨论区的代码,怎么都跟我的不一样,后来才发现原来我的英文翻译错了,具体是怎么回事呢?接着往下看吧
正文
原题:
链接:删除链表的倒数第N个节点
Given a linked list, remove the n-th node from the end of list and return its head.
Example:
Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Follow up:
Could you do this in one pass?
题目大意
给你一个整型的链表以及一个整数n,让你删除链表的倒数第N个节点,比如链表1 -> 2 -> 3 -> 4 ->5,n为2,则删除倒数第2个节点4,并将链表的头节点返回,返回之后的链表应该变成1 -> 2 -> 3 -> 5
思路1:
我心想:挺简单的啊,用一个List存储链表的每个节点,然后直接remove倒数第N个元素,并将List赋值给链表不就行了,如下图所示:
代码
public ListNode removeNthFromEnd(ListNode head, int n) { List<Integer> list = new ArrayList<>(); //向list中添加链表元素 while (head != null) { list.add(head.val); head = head.next; } //list删除倒数第n个元素 list.remove(list.size() - n); //若list为空了,就无需继续判断,直接返回null if (list.size() == 0) { return null; } //新建一个临时的链表,并指向head ListNode temp = new ListNode(0); head = temp; //往temp中添加list的元素 for (int i = 0; i < list.size(); i++) { temp.val = list.get(i); if (i != list.size() - 1) { temp.next = new ListNode(0); temp = temp.next; } } return head; }
代码讲解
以上代码应该很好懂,思路就是用list存储链表的每个节点,删除之后赋值给链表,提交代码也成功通过了,但是总感觉不对劲,这是一道中等难度的题,不可能这么简单吧
这时候我注意到了题目中的Follow up,一开始我把它翻译成你能一次通过吗?,但是我查看了中文版的leetcode,才发现是另外一种翻译
如上图所示,中文版leetcode把它翻译成你能尝试使用一趟扫描实现吗?,原来这才是重点!
刚刚的解法中,我使用了两趟扫描,一趟扫描链表节点、一趟扫描重新赋值,那如果只使用一趟扫描需要怎么做呢?
思路2:
其实第一种做法中使用list存储的一个目的就是为了记录链表的长度,从而可以方便地删除倒数第n个节点,那如果只用一趟扫描的话,list肯定不能用了。这时候我们可以从如何找到倒数第n个节点的角度出发,首先看一下下面这张图,图中链表标出了两个节点,其中一个节点是第n个节点,另外一个节点是倒数第n个节点:
我们可以得知head到n1的距离等于n2到rail的距离,借助两个指针p1、p2,其中p1指向head、p2指向n1,如下图所示:
让p1和p2同时移动,直到p2指向最后一个节点,此时p1会指向哪里呢(建议同学思考一下)?
没错,p1指向了n2的位置,也就是倒数第n个位置,如下图所示:
这是为什么呢?其实很简单,由图中得知head到n1的距离等于n2到rail的距离,因此head到n2的距离也就等于n1到rail的距离,所以让它们同时移动且p2到达rail位置时,p1就可以指向n2的位置,也就是倒数第n个位置!
有一点需要注意的,题目让我们删除倒数第n个节点,但是我们不需要找倒数第n个节点,而是要找倒数第n + 1个节点,因为删除倒数第n个节点的步骤是将第n + 1个节点的next指针指向第n - 1个节点,我们不需要找到第n个节点,如下图所示:
代码
public ListNode removeNthFromEnd(ListNode head, int n) { //这里看作是头节点,由于原链表head是没有头节点的,操作起来会比较麻烦,所以需要新增一个头节点 ListNode newHead = new ListNode(0); ListNode p1 = newHead; ListNode p2 = newHead; //此时的p2就变成了一个拥有头节点的head链表 p2.next = head; //将p2移动到第n个节点(相对于原链表而言) for (int i = 0; i < n; i++) { p2 = p2.next; }//p1、p2同时移动,直到p2指向最后一个节点,p1指向了倒数第n+1个节点 while (p2.next != null) { p2 = p2.next; p1 = p1.next; }p1.next = p1.next.next;return newHead.next; }
代码讲解
由于原题没有给头节点,这会导致我们在查找节点时出现一些麻烦,因此我们新建了一个newHead的头节点,并让p1跟p2指向newHead,p2.next = head; 这一句代码使p2变成了一个拥有头节点的head链表,假设n = 2,原链表为
1 -> 2 -> 3 -> 4 -> 5
那么p2就变成了
0 -> 1 -> 2 -> 3 -> 4 -> 5
for (int i = 0; i < n; i++) { p2 = p2.next; }
上面的代码将p2移动到第n个节点(相对于原链表而言),即移动到了元素为2的节点
while (p2.next != null) { p2 = p2.next; p1 = p1.next; }
这段代码的作用就是让p1、p2同时移动,直到p2移动到最后一个元素停止
此时p1移动到了倒数第n+1个元素的位置,将倒数第n个元素从链表中删除,即
p1.next = p1.next.next;
提交代码!KO!
总结
一开始我以为只使用英文版的leetcode就行了,直到今天因为英文翻译的问题,误解了题目的意思,这时才意识到中英版本的leetcode可以互相参考,平时刷题可以用英文的,若实在不懂的话再查看中文版本的作为辅助,或许这样就可以避免一些问题了。
好了,这就是今天的题了,送给大家一句话:
有些事情本来很遥远,你争取,它就会离你愈来愈近!——来源《破风》
共勉!
- 点赞
- 收藏
- 分享
- 文章举报
- 【LeetCode题解】19_删除链表的倒数第N个节点(Remove-Nth-Node-From-End-of-List)
- [LeetCode] 19. Remove Nth Node From End of List 删除链表的倒数第N个节点 @python
- [C++]LeetCode 19: Remove Nth Node From End of List(删除链表中倒数第n个节点)
- leetcode19 Remove Nth Node From End of List(删除链表的倒数第N个节点)
- leetcode-19. Remove Nth Node From End of List(删除链表倒数第N个节点)
- [LeetCode-19] Remove Nth Node From End of List(删除链表中倒数第N个节点)
- LeetCode(Remove Nth Node From End of List)删除链表倒数第n个节点
- [LeetCode]—Remove Nth Node From End of List 删除链表的倒数第n个节点
- LeetCodet题解--19. Remove Nth Node From End of List(删除链表的倒数第n个元素)
- [LeetCode] 19. Remove Nth Node From End of List 移除链表倒数第N个节点
- 【LeetCode】Remove Nth Node From End of List 删除链表中倒数第n个节点- Easy +
- LeetCode 19. Remove Nth Node From End of List--删除链表的倒数第n个结点
- leetcode_[python/C++]_19. Remove Nth Node From End of List(删除链表末第n个节点)
- 【Leetcode】19. Remove Nth Node From End of List - 删掉链表倒数第n个节点
- leetcode:Remove Nth Node From End of List(删除链表倒数第n个节点)【面试算法题】
- leetCode 19.Remove Nth Node From End of List(删除倒数第n个节点) 解题思路和方法
- [Leetcode] remove nth node from the end of list 删除链表倒数第n各节点
- LeetCode 19 Remove Nth Node From End of List 移除倒数第N个节点
- Remove Nth Node From End of List 链表删除倒数第N个元素@LeetCode
- Leetcode:19 Remove Nth Node From End of List(在链表中删除倒数第n个数)