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

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

示例 1:


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

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

        受到上个题的启发,这个题依然用快慢指针。删除结点要找到要删除结点的上一个节点,也就是哑结点,快指针 先行,慢指针后行,快慢指针之间相差题目所给的倒数几个,倒数第二个,快指针到达末尾,慢指针到达倒数第三个,也就是快慢指针相差n个。所以就是快指针先走到末尾,慢指针到达哑结点。代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode d=new ListNode(0,head);
        ListNode slow=d,fast=head;
        int count=0;
        while(fast!=null&&fast.next!=null){
            fast=fast.next;
            if(count!=n){
                count++;
            }           
            if(count==n){
                slow=slow.next;
            }
        }
            slow.next=slow.next.next;
        return d.next;
    }
}

这里有个细节需要在原链表头前插入一个结点。如果slow和fast同时从head出发,会出现空指针问题.因为当count等于n的时候,slow已经往下走了。所以要想达到slow从首结点出发的目的,需要在原链表头前插入一个结点.        

 还有另外一个原因是如果只有一个结点,删除之后应该原链表没有了,需要返回原链表头,所以需要一个指向原链表的结点。最后return d.next 就是这个原因。

老规矩 看题解学习其他思路。

看到从后往前,便可以想到栈(我居然把这个忘干净了!!!)先进后出,那么将这个链表压入栈中,倒数第n个,便是出栈第n-1个,直接将这个结点删除,即可达成目的。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);
        Deque<ListNode> stack = new LinkedList<ListNode>();
        ListNode cur = dummy;
        while (cur != null) {
            stack.push(cur);
            cur = cur.next;
        }
        for (int i = 0; i < n; ++i) {
            stack.pop();
        }
        ListNode prev = stack.peek();
        prev.next = prev.next.next;
        ListNode ans = dummy.next;
        return ans;
    }
}

 值得一提的是,

Stack.peek()  peek()函数返回栈顶的元素,但不弹出该栈顶元素。

Stack.pop() pop()函数返回栈顶的元素,并且将该栈顶元素出栈。

开拓思路!任重道远!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值