美文网首页
基于单链表的回文序列判断

基于单链表的回文序列判断

作者: Ridiculous_one | 来源:发表于2019-07-06 03:13 被阅读0次

本文首发于 LOGI'S BLOG,由作者转载。

问题

假如字符串使用单向链表存储,如何判断其是否为回文序列?

思路

S1. 定义快慢指针,快指针每次走两步,慢指针每次走一步同时将所经链表指针逆向,直到快指针走至表尾(next 为 null),此时慢指针刚好处于中点(对于元素个数为偶数的链表,处于下中点,即后半部分的首节点)。

S2. 同时遍历前后半段链表,如完全相同则为回文序列。

S3. 恢复被逆序的链表。

举例

奇数序列:ABCBA

A -> B -> C -> B -> A // 初态
A <- B <- C -> B- > A // S1 后
         slow

偶数序列:ABCCBA

A -> B -> C -> C -> B -> A // 初态
A <- B <- C <- C -> B -> A // S1 后
              slow

时空复杂度

S1 的时间复杂度为 O(n/2),空间复杂度 O(1)。
S2 的时间复杂度为 O(n/2),空间复杂度 O(1)。
S3 的时间复杂度为 O(n/2),空间复杂度 O(1)。
最终总的时间复杂度就是 O(n),空间复杂度 O(1)。

代码实现

package com.logi.algorithm;

/**
 * @author LOGI
 * @version 1.0
 * @date 2019/7/6 0:46
 */
public class PalindromeExamination {
    public static void main(String[] args) {
        PalindromeExamination.testSequence("ABCBA");
        PalindromeExamination.testSequence("ABCBB");
        PalindromeExamination.testSequence("ABCCBA");
        PalindromeExamination.testSequence("ABCCBB");
    }

    public static void testSequence(String sequence) {
        SinglyLinkedList list = new SinglyLinkedList(sequence);
        String determination = list.isPalindrome() ? "" : "not ";
        System.out.println(sequence + " is " + determination + "a palindrome.");
    }
}

class SinglyLinkedList {
    Node head;

    public SinglyLinkedList(String sequence) {
        for (int i = sequence.length() - 1; i >= 0; i--) {
            this.insert(sequence.charAt(i));
        }
    }

    public void insert(char elem) {
        Node newNode = new Node(elem);
        newNode.next = this.head;
        this.head = newNode;
    }

    public boolean isPalindrome() {
        if (this.head == null || this.head.next == null) {
            return false;
        }
        Node prev = null;
        Node next;
        Node slow = this.head;
        Node fast = this.head;

        // 判断 fast.next 是否为 null,在此之前也要保证 fast 不为 null
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            // 逆向 slow.next
            next = slow.next;
            slow.next = prev;
            prev = slow;
            slow = next;
        }
        // 保存中点用于恢复
        Node mid = slow;
        Node midPre = prev;

        // 奇数序列,从中点之后开始比较
        if (fast != null) {
            slow = slow.next;
        }
        while (slow != null) {
            if (slow.data != prev.data) {
                return false;
            }
            slow = slow.next;
            prev = prev.next;
        }

        // 再次逆向 midPre.next,恢复链表
        while (midPre != null) {
            next = midPre.next;
            midPre.next = mid;
            mid = midPre;
            midPre = next;
        }
        return true;
    }
}

class Node {
    Node next;
    char data;

    public Node(char elem) {
        this.data = elem;
        this.next = null;
    }
}

相关文章

  • 基于单链表的回文序列判断

    本文首发于 LOGI'S BLOG,由作者转载。 问题 假如字符串使用单向链表存储,如何判断其是否为回文序列? 思...

  • 初级算法-链表-回文链表

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

  • 234. 回文链表

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

  • Python编程题47--回文链表

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

  • 回文链表 2022-03-05 周六

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

  • Swift - LeetCode - 回文链表

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

  • 算法题解:判断链表是否为回文链表

    大家好,我是前端西瓜哥,今天来做一道算法题。 给一个单链表,判断是否为回文链表。 所谓回文,就是左右值对称相同的链...

  • 02-14:leetcode重刷8之哈希与数组

    链表: 判断链表是否环形、是否回文 1、是否链表 #Definitionforsingly-linkedlist....

  • 【日拱一卒】链表——回文判断

    需求 判断一个链表是否是回文链表 回文的形式大家应该都知道,类似 这种对称的方式都是回文。 难点 如果将链表形式换...

  • Algorithm小白入门 -- 单链表

    单链表递归反转链表k个一组反转链表回文链表 1. 递归反转链表 单链表节点的结构如下: 1.1 递归反转整个单链表...

网友评论

      本文标题:基于单链表的回文序列判断

      本文链接:https://www.haomeiwen.com/subject/sksuhctx.html