心路历程:
这道题折磨了我很久,本来想看答案的,最后没有看到,硬是被自己做出来了,就是,有点憋屈,这里面有点经验教训如下:
1、对快指针先走n步后,慢指针再走,之后,到达结尾的时候,慢指针在哪里是有点模糊的,快指针在哪里也是。
这里再强调下,快指针走完了,一点是走到空节点,null里面去的;
慢指针,则是,当快指针,走到结尾时,自动指导了倒数第n个节点。
2、这里现在n步,知道0时,才听停止快指针的脚步,让慢指针跟着走,可以直接用
while(n!=0) { fast = fast.next; n--; } 实现就好了。
3、还有这道题目,有个机关,就是要删除的倒数第n个节点,有可能是头节点,
很容易导致空指针异常的问题,所以,定义了一个临时的头节点填充,并初始化pre = res;
这样当
ListNode res = new ListNode(-1);
res.next = head;
解题思路:
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 官方的写法,增加了我的注释 * @param head ListNode类 * @param n int整型 * @return ListNode类 */ public ListNode removeNthFromEnd (ListNode head, int n) { // 这里是用一个表头很有意思 // 当要删除的节点是head头节点时,就可以作为缓冲 // 所以,下面ListNode pre = res,就是这样巧妙的设计 ListNode res = new ListNode(-1); res.next = head; // 快指针先走n步 ListNode fast = head; while (n != 0) { fast = fast.next; n--; } // 快慢指针一起走,到头后慢指针就指到了倒数第n个节点了 ListNode cur = head;//如果fast为空,就是说明删除的是头节点 ListNode pre = res; //fast为空,说明是删除头节点, //之后用pre的next指向下个节点,就删除了头节点了 while (fast != null) { pre = cur; // 用于指到倒数第n+1个节点 cur = cur.next; //用于指到倒数第n个节点 fast = fast.next; //用于走到头 } // 删除当前指针 pre.next = cur.next; return res.next; } /** * 我自己的写法,靠自己倒腾出来的 */ public ListNode removeNthFromEnd2 (ListNode head, int n) { ListNode newHead = new ListNode(0); newHead.next = head; // 先遍历到第n个节点, int i = 0; ListNode fast = head; while(i < n) { fast = fast.next; i++; } // 说明要删除的是头节点 if(fast == null) { ListNode temp = head.next; head.next = null; head = temp; return head; } // 否则说明删除的非头节点的 ListNode slow = head; ListNode prev = null; while(fast!=null) { prev = slow; slow = slow.next; fast = fast.next; } prev.next = slow.next; return head; } }