1 题目描述(中等难度)

2 我的解法
思路:需要两遍扫描才可得到结果,不够高效
- 计算链表的长度,计算需删除正数第几个节点
- 找到需要删除的节点的前序,直接删去节点即可
1/**2* Definition for singly-linked list.3* public class ListNode {4* int val;5* ListNode next;6* ListNode(int x) { val = x; }7* }8*/9class Solution {10public ListNode removeNthFromEnd(ListNode head, int n) {11if(head==null)return null;12//先计算节点个数13int dotnum=0;14ListNode l3=head;15while(l3!=null)16{17dotnum++;18l3 = l3.next;19}20//删除到处第n个节点21int delindex=dotnum-n;22if(delindex==0)return head.next;//如果删除第一个节点,则直接返回23ListNode pre=head;24for(int i=0 ;i<delindex-1;i++)//找到被删节点的前一个节点25pre=pre.next;26l3=pre.next;//被删节点27pre.next=l3.next;28return head;29}30} - 时间复杂度:O(n)
- 空间复杂度:O(1)
3 解法二
使用快慢指针:优点这里我们用到的快慢指针其实没有必要,快慢指针的一个优点是,不需要知道链表长度就可以找到倒数第 n 个节点。
问题:我的解法没有考虑,通过一次遍历的方式解决问题。
方法:设置快慢指针,两者间隔n个节点,当快指针到达链尾时,慢指针正好指向删除节点的前序节点。1public ListNode removeNthFromEnd(ListNode head, int n) {2 ListNode dummy = new ListNode(0);3 dummy.next = head;//加空指针,不用特判删除链首的情况4 ListNode first = dummy;//快指针5 ListNode second = dummy;//慢指针6 //第一个指针先移动 n 步7 for (int i = 1; i <= n + 1; i++) {8 first = first.next;9 } 10 //第一个指针到达终点停止遍历11 while (first != null) {12 first = first.next;13 second = second.next;14 }15 second.next = second.next.next;//删去节点16 return dummy.next;17}
不设置空指针版1class Solution {2 public ListNode removeNthFromEnd(ListNode head, int n) {3 ListNode first = head;4 ListNode second = head;5 for(int i=0;i<=n;i++)6 {7 if(first==null)8 return head.next;9 first = first.next;10 }11 while(first!=null)12 {13 first=first.next;14 second=second.next;15 }16 second.next=second.next.next;17 return head;18 }19}