ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

19. 删除链表的倒数第 N 个结点

2021-12-05 19:32:32  阅读:124  来源: 互联网

标签:count head ListNode 19 节点 链表 next 倒数第


目录

19.删除链表的倒数第N个节点

题目

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

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:

输入:head = [1], n = 1
输出:[]
示例 3:

输入:head = [1,2], n = 1
输出:[1]

提示:

链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解-暴力

要删除链表中的某个节点,需要知道其前一个节点。对于头节点来说,其没有前一个节点,因此,需定义虚拟头节点dummy

链表的第x个节点,就必然需要遍历。
第一遍遍历知道整个链表的长度,把倒数的节点转换成正数的第x个节点
第二遍遍历删除倒数第n个节点

ListNode dummy = new ListNode(); //增加一个无数据的节点,统一边界节点操作
dummy.next = head;
int count = 1;
while(head.next!=null){
	head = head.next;
	count++;
}
n = count - n + 1;//删除从头到尾的第n个
count = 1;
ListNode pre = dummy;
head = dummy.next;
for(;count!=n;count++){
	pre=head;
	head = head.next;
}//找到了要删除的元素
//进行删除
pre.next = head.next;
return dummy.next;

题解-哈希表

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

第二遍遍历主要是去找需要删除的元素,那么如果我们使用哈希表在第一次遍历的时候就把位置信息记录下来,那么就不需要再遍历去找了。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(); 
        dummy.next = head;
        HashMap<Integer,ListNode> map = new HashMap<>();
        int count = 0;
        map.put(count,dummy);
        while(head!=null){
            count++;
            map.put(count,head);
	        head = head.next;
        }
        //计算删除的元素位置
        n = count-n+1;
        //获取要删除的元素前一个元素,与当前元素
        ListNode pre = map.get(n-1);
        head = map.get(n);    
        pre.next = head.next;
        return dummy.next;
    }
}

题解-双指针

之前的链表题使用了双指针,这里我们考虑一下双指针,双指针适合用于划分区间,距离等。

需要遍历一遍的主要原因时找到链表的长度,也就是需要遍历到最后一个节点后面,通过最后一个节点的后面再去定位倒数的节点。那么这里我们用一个指针指向最后,一个指针指向需要删除的节点前一个节点就可以了。

这里要删除的是链表中倒数第2个节点,slow指向需要删除的节点的前一个节点。
那如何确定好slow指向的位置?当指针fast指向null时,它与指针slow之间相差2个节点,刚好是n=2。

先让fast走n+1步,然后再一起走

class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode dummyHead = new ListNode(0);
    dummyHead.next = head;

    // 慢指针初始指向虚拟头结点
    ListNode slow = dummyHead;
    // 快指针初始指向虚拟头结点
    ListNode fast = dummyHead;

    // 快指针先向前移动n+1步
    for(int i = 0; i <= n; i++) {
        fast = fast.next;
    }

    // 快慢指针同时向前移动,直到快指针指向null
    while (fast!=null){
        fast = fast.next;
        slow = slow.next;
    }

    // 慢指针的下一个节点即待删除节点
    ListNode delNode = slow.next;
    // 慢指针的后继指针指向待删除节点的下一个节点
    // 这样就将待删除节点删除了
    slow.next = delNode.next;
    delNode.next = null;
    return dummyHead.next;
}

}

标签:count,head,ListNode,19,节点,链表,next,倒数第
来源: https://www.cnblogs.com/rananie/p/15646783.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有