一、题目要求:
二、解题:
代码:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre = head; // 便于遍历链表
int last = count(head) - n; // 计算出待删除链表节点的前一个节点。如5个节点,删除倒数第2个,那么待删除节点的前一节点就是3.
if( last == 0 ){ // 表示要删除的就是head节点。如:只有一个节点,删除倒数第一个节点
return head.next;
}
for(int i = 1; i < last; i++){
pre = pre.next; // 获取到待删除节点的前一节点
}
pre.next = pre.next.next; // 跳过待删除节点指向待删除节点的下一节点
return head;
}
// 计算节点个数
public int count(ListNode head){
int len = 0;
while(head != null){
len += 1;
head = head.next;
}
return len;
}
}
思路:不使用双指针,使用计算位置的方法进行解题。还可使用先讲链表逆序后删除的解法
1. 遍历链表,获取链表的长度(len)。
2. 根据链表的长度和要删除的倒数第n项计算出要删除的节点的正数位置,即第length - n + 1项。 3. 如果要删除的节点是头节点,则直接返回头节点的下一个节点作为新的头节点。
4. 否则,重新遍历链表,找到要删除节点的前一个节点pre。
5. 将prev的next指针指向要删除节点的下一个节点,完成删除操作。
这种方法的时间复杂度同样为O(n),其中n是链表的长度。相比于双指针方法,这种方法需要进行两次遍历,但是逻辑更加直观简单。