Java-面试链表- 1、判断是否构成回文结构 2、删除链表倒数第k个节点

本文探讨了两种链表操作问题:一是如何判断单链表是否构成回文,通过找到链表中点并反转后半段,然后逐一对比节点值来实现;二是如何删除链表倒数第k个节点,使用快慢指针找到目标节点的前驱,然后进行删除操作。这两题均涉及链表的高效操作技巧。

目录

判断链表是否构成回文结构

题目介绍:

题目分析:

代码:

删除链表倒数第k个节点

题目介绍

题目分析

代码


判断链表是否构成回文结构

题目介绍:

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

如图,两组链表的val值便构成回文。

题目分析:

分析:

判断链表是否回文,应将链表倒数第一个节点值和第一个节点的值,依次比较。

思路:

1、将链表后半段反转。

①定义快慢引用都指向链表头,快引用一次向后走两个节点,慢引用一次走一个节点,直到快引用为空或者next域为空,两个引用都停下。找到链表中间节点。

②改变节点指向,将链表后半段节点反转。

2、将指向头节点的引用head和指向尾部的引用prev的节点的val进行比较,逐步向后移动。

3、循环停止条件:

①当对应节点的val存在不相等,循环停止,返回false

当链表长度为偶数时,当head.next == prev时且对象的val相等时,循环结束,构成回文结构。

代码:

找到中间节点:

        ListNode fast = this.head;
        ListNode slow = this.head;
        while (fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }

将链表反转:

        ListNode prev = slow;
        ListNode cur = prev.next;
        while (cur != null){
            ListNode curNext = cur.next;
            cur.next = prev;
            prev = cur;
            cur = curNext;
        }

逐个比较:

        while (head != prev ){
            if (head.val != prev.val){
                return false;
            }
            if (head.next == prev){
                return true;
            }
            head = head.next;
            prev = prev.next;
        }
        return true;

全部代码:

    public boolean chkPalindrome(){
        if (this.head == null){
            return true;
        }
        ListNode fast = this.head;
        ListNode slow = this.head;
        while (fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        ListNode prev = slow;
        ListNode cur = prev.next;
        while (cur != null){
            ListNode curNext = cur.next;
            cur.next = prev;
            prev = cur;
            cur = curNext;
        }
        while (head != prev ){
            if (head.val != prev.val){
                return false;
            }
            if (head.next == prev){
                return true;
            }
            head = head.next;
            prev = prev.next;
        }
        return true;
    }

删除链表倒数第k个节点

题目介绍

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

提示:给定的n一定为有效值

题目分析

分析:

先找到倒数第n个节点再将其删除。

思路:

1、找链表的特殊位置优先考虑快慢指针。

2、找到要删除节点的前驱,后删除指定节点。

代码

快指针先移动n个步

        if (head == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        while (n != 0) {
            fast = fast.next;
            n--;
        }

若快指针已经走完,则可以确定要删除的节点为头节点。

如下链表:返回倒数第5个节点,此时快指针走完

此时代码应加判断:

if (fast == null) {
    return head.next;
}

 快慢指针逐个后走,指定快指针的next域为空停止,找到节点前驱;删除节点:

        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;

全部代码

   public ListNode removeNthFromEnd(ListNode head, int n) {
        if (head == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        while (n != 0) {
            fast = fast.next;
            n--;
        }
        if (fast == null) {
            return head.next;
        }
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return head;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爆裂突破手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值