2021-06-22删除链表的倒数第n个节点

leetcode每日一题

今天的题目都比较简单,因此多刷几个

1:删除链表中的节点

题目链接:https://leetcode-cn.com/problems/delete-node-in-a-linked-list/

题目描述:

请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为 要被删除的节点 。

例子:

输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

思路:直接将node节点的i爱一个节点的值赋值给node节点,然后将node的指向指到下下个节点即可。

代码:
// An highlighted block
//输入:head = [4,5,1,9], node = 5
        //输出:[4,1,9]
        public void deleteNode(ListNode node) {
            node.val = node.next.val;
            node.next = node.next.next;
        }

2:移除链表中的元素

题目链接:https://leetcode-cn.com/problems/remove-linked-list-elements/

题目描述:

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

例子:

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

思路

因为头节点可能被删除,因此要定义一个节点,这个节点的next指针指向head,然后另外一个节点指向这个节点,开始遍历链表找到节点的值和给定的值相等的节点,改变指针指向

代码:
// An highlighted block
 //输入:head = [1,2,6,3,4,5,6], val = 6
        //输出:[1,2,3,4,5]
        public ListNode removeElements(ListNode head, int val) {
            ListNode dummy = new ListNode(-1);//定义一个呀节点,因为头节点也有可能被删除
            dummy.next = head;
            ListNode tempNode = dummy;
            while (tempNode != null && tempNode.next != null) {
                if (tempNode.next.val == val) {
                    tempNode.next = tempNode.next.next;
                } else {
                    tempNode = tempNode.next;
                }
            }
            return dummy.next;
        }

3:删除链表的倒数第n的节点

题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/

题目描述:

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

例子:

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

思路

首先统计链表元素的个数ans,然后遍历ans-n次,遍历之后将节点的next指向next的next。具体看代码吧。

代码:
    //输入:head = [1,2,3,4,5], n = 2
        //输出:[1,2,3,5]
        //1,2   2
        public ListNode removeNthFromEnd(ListNode head, int n) {
            ListNode temp = head;
            int ans = 0;//记录链表元素个数
            //首先遍历链表,统计链表元素个数
            while (temp != null) {
                temp = temp.next;
                ans++;
            }
            if (ans == 1) return null;//[1] 1这样的情况
            ListNode dummy = new ListNode(-1);//需要定义一个呀节点,因为头节点可能会被删除
            dummy.next = head;
            ListNode tempNode = dummy;
            //然后遍历链表ans-n次,修改指针指向
            for (int i = 0; i < ans - n; i++) {
                tempNode = tempNode.next;
            }
            tempNode.next = tempNode.next.next;
            return dummy.next;
        }

上面需要遍历两次链表,其实还可以进行优化

思路
当链表总长度是k时,如果要删除倒数第n个节点(假设n小于k),那么首先要找到第k-n个节点,k-n这个节点就是要删除的节点的前一个节点。当找到k-n这个节点就好办了,直接将k-n的next指针指向下下一个节点即可。我们需要两个指针a和b。b指针先走n步,接着a和b指针同时往前走,当b指针走到链表末尾时,a指针就正好走到要删除的节点的前一个位置了,最后a节点的next指针指向下下一个节点,就可以完成删除操作了。

代码:
    public ListNode removeNthFromEnd2(ListNode head, int n) {
            //增加呀节点方便处理头节点
            ListNode p = new ListNode(-1);
            p.next = head;
            ListNode a = p;
            ListNode b = p;
            //第一个循环,b指针先往前走n步
            while (n > 0 && b != null) {
                n--;
                b = b.next;
            }
            //假设整个链表长度是5,n是10,那么第一次遍历完之后b就等于null
            //于是后面的判断就不用做了,直接返回
            if (b == null) {
                return head;
            }
            //第二次,b指针走到最后,a指针也跟着走
            //当遍历结束时,a指针就指向要删除的节点的前一个位置
            while (b.next != null) {
                a = a.next;
                b = b.next;
            }
            //删除节点并返回
            a.next = a.next.next;
            return p.next;
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值