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;
    }
}
相关推荐
️是781 小时前
信息奥赛一本通—编程启蒙(3346:【例60.3】 找素数)
数据结构·c++·算法
captain3761 小时前
map和set
数据结构·算法
tankeven2 小时前
【无标题】
数据结构·c++·算法
jing-ya3 小时前
day 59 图论part10
java·开发语言·数据结构·算法·图论
不染尘.3 小时前
最短路径之Bellman-Ford算法
开发语言·数据结构·c++·算法·图论
zx_zx_1233 小时前
定长滑动窗口和不定长滑动窗口
数据结构·算法
自信150413057594 小时前
选择排序算法
c语言·数据结构·算法·排序算法
仰泳的熊猫5 小时前
题目2580:蓝桥杯2020年第十一届省赛真题-分类计数
数据结构·c++·算法·蓝桥杯
qyzm5 小时前
牛客周赛 Round 136
数据结构·python·算法
Magic--5 小时前
从入门到精通:快速排序的核心原理、实现与优化
数据结构·算法·排序算法