Leetcode刷题链表之删除链表的倒数第N个节点

删除链表的倒数第N个节点(java、python)

1、问题描述

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

示例:

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

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

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list

2、问题分析

首先双重遍历肯定能解决问题,我们来找一下解题规律,设链表长度为m,则要删除的节点位置为m-n+1
当m=5,n=2时,删除第4个节点。
既然这样不妨设置两个指针p,q,且指针的位置距离一直保持相差n个节点,设p的位置为x,则q的位置为x+n+1,显然当p,q指针一直向右移动时,当q指向null(链表尾结点后的空节点)时(x+n+1=m+1),p的位置为m-n,而删除的节点位置为m-n+1,所以要删除的节点为p指针位置的下一个节点,这样一次遍历就能完成。
最好在链表开头加一个虚拟节点,否则删除第一个节点时会有问题,因为删除的是p的下一个节点,这个时候p刚好在虚拟节点位置。

3、代码

java

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode p = new ListNode(0);//虚拟节点
        p.next = head; 
        ListNode q = p;
        ListNode first = p; //临时存储虚拟头节点
        for(int i=1;i<=n+1;i++){ //循环n+1次使q指针和p指针位置差n个节点
            q = q.next;
        }
        while(q!=null){ //循环遍历整个链表
            p = p.next;
            q = q.next;
        }
        ListNode temp = p.next; //要删除的节点
        p.next = temp.next; //p的节点指向要删除的节点的下一个节点,达到目的
        return first.next; //返回头节点
    }
   
}

python

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        p = ListNode(0)
        p.next = head
        q = p
        first = p
        for i in range(n+1):
            q = q .next
        while(q!=None):
            p = p.next
            q = q.next
        temp = p.next
        p.next = temp.next
        return first.next
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值