基于单向链表数据结构的回文字符串判断

前言

学习了极客时间王铮老师的《数据结构与算法之美》中《06 | 链表(上):如何实现LRU缓存淘汰算法?》,课后思考留了一道算法题,
给定一个字符串,判断是否是回文字符串,而且呢,这个字符串不是普通的字符串,字符串中各个字符是以单向链表的数据结构首尾相连,看起来像下面这样:1 -> 2 -> 3 -> 0 -> 3 -> 2 -> 1,我们来一起看下这个算法可以如何实现。

算法

算法简述

这里介绍一种快慢指针的方法(所谓快慢指针,说白了就是两个变量而已)。
开始时,快慢指针都指向头结点,然后从头结点开始,,快指针每次走两步,慢指针每次走一步。
对于一个长度为奇数的链表,当快指针走到尾结点时,慢指针刚好走到这个链表最中间的那个节点。从头结点开始,慢指针走过的节点 next 引用都反转方向,指向之前指向自己的那个节点。然后从中间向两侧开始逐节点对比,一直对比到头尾节点,如果每次对比,内容都相同,则说明是一个回文字符串。

算法可视化

上面大致理清了思路,为了将思路更清晰,在撸代码之前让更多小伙伴理解,我用图片来说明一下。
我们还是基于长度为奇数的单向链表,因为长度为偶数的单向链表相对容易一些。

代码实现

这里,我没加注释,上面已经图文讲解的很详细了。

package org.xueliang.algorithm.linkedlist;

/**
 * @author xueliang
 * @since 2020-07-25 00:01
 */
public class Palindrome {

    public static void main(String[] args) {
        Node a = new Node("1", null);
        Node b = new Node("2", a);
        Node c = new Node("3", b);
        Node d = new Node("0", c);
        Node c1 = new Node("1", d);
        Node b1 = new Node("2", c1);
        Node a1 = new Node("3", b1);

        Node fast = a1;
        Node slow = a1;
        Node pre = null;

        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            Node slowNext = slow.next;
            slow.next = pre;
            pre = slow;
            slow = slowNext;
        }
        if (fast != null) {
            slow = slow.next;
        }
        boolean isPalindrome = true;
        while (pre != null) {
            if (!pre.text.equals(slow.text)) {
                isPalindrome = false;
                break;
            }
            pre = pre.next;
            slow = slow.next;
        }

        System.out.println("是否是回文字符串:" + isPalindrome);
    }

    static class Node {

        Node(String text, Node next) {
            this.text = text;
            this.next = next;
        }

        private String text;

        private Node next;

        @Override
        public String toString() {
            return "Node{id:" + Integer.toHexString(hashCode()) + ",text:" + text + "}";
        }
    }
}

相关阅读

负载均衡算法之一致性 Hash 算法实现
负载均衡算法之加权轮询算法实现