hot100 234.回文链表

思路:

1.先考虑怎么判断一个字符串是不是回文字符串。可以从最左最右开始,比较第一个字母和最后一个字母是不是一样的,如果第一个字母和最后一个字母是一样的,那么就继续比较第二个字母和倒数第二个字母,以此类推。

2.如何快速找到链表的最后一个节点、倒数第二个节点、倒数第三个节点......?

3.首先可以找到链表的中间节点:

(1)如果链表有奇数个节点,就找正中间的节点。

(2)如果链表有偶数个节点,就找正中间右边的节点。

4.然后把中间节点到链表末尾反转,如上图所示,反转后得到链表6->5->4,其头节点记作head2,这样就能从head2开始,依次访问原链表的最后一个节点、倒数第二个节点、倒数第三个节点...。

5.最后,同时遍历head和head2这两个链表,每次循环判断head.val是否等于head2.val,若不相等,则返回false。循环直到head2链表遍历结束,如果循环中没有返回false,则说明链表是回文的,返回true。

6.注意:

(1)第一张图中的2->3,在反转链表后,并不会断开。第一张图反转链表后,我们得到了两条链表:一条是1->2->3,另一条是5->4->3。

(2)第二张图中的3->4,在反转链表后,并不会断开。第二张图反转链表后,我们得到了两条链表:一条是1->2->3->4,另一条是6->5->4。这意味着代码在写循环的时候,循环条件要判断head2是否为空而不是head是否为空,否则会错误地多循环一次,导致访问head2.val出现空指针异常。

7.问:为什么不反转整个链表,这样也可以访问原链表的最后一个节点、倒数第二个节点、倒数第三个节点......?

答:

因为还要从head开始遍历链表,访问原链表的第一个节点、第二个节点、第三个节点......。如果反转整个链表,那么链表前半段的结构就被破坏了。

8.复杂度分析:

(1)时间复杂度:O(n),其中n是链表的长度(节点个数)。

(2)空间复杂度:O(1)。

附代码:

java 复制代码
class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode mid = middleNode(head);
        ListNode head2 = reverseList(mid);
        while(head2 != null){
            if(head.val != head2.val){ // 不是回文链表
                return false;
            }
            head = head.next;
            head2 = head2.next;
        }
        return true;
    }

    //求链表的中间节点
    //快慢指针法,对于无环链表,可让快指针每次走两步,慢指针每次走一步,当快指针走到结尾处时慢指针到达中间节点
    private ListNode middleNode(ListNode head){
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
    //反转链表
    private ListNode reverseList(ListNode head){
        ListNode pre = null;
        ListNode cur = head;
        while(cur != null){
            ListNode tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
}
相关推荐
2301_810730106 分钟前
python第四次作业
数据结构·python·算法
春栀怡铃声19 分钟前
认识二叉树~
c语言·数据结构·经验分享·c·编译
仰泳的熊猫24 分钟前
题目1434:蓝桥杯历届试题-回文数字
数据结构·c++·算法·蓝桥杯
ygklwyf34 分钟前
模拟退火算法零基础快速入门
数据结构·c++·算法·模拟退火算法
寄存器漫游者1 小时前
数据结构 二叉树与哈希表
数据结构·散列表
Sayuanni%32 小时前
数据结构_Map和Set
java·数据结构
执着2592 小时前
力扣hot100 - 144、二叉树的前序遍历
数据结构·算法·leetcode
近津薪荼2 小时前
递归专题(4)——两两交换链表中的节点
数据结构·c++·学习·算法·链表
散峰而望2 小时前
【算法竞赛】树
java·数据结构·c++·算法·leetcode·贪心算法·推荐算法
鱼很腾apoc2 小时前
【实战篇】 第14期 算法竞赛_数据结构超详解(下)
c语言·开发语言·数据结构·学习·算法·青少年编程