判定链表是否是回文

[!Tip]

本节源代码见Github链接🔗


问题描述

判定链表是否是回文(顺读和倒读都是一样的)?


核心思路

参考08-找到链表的中间结点,将链表平均分割成两部分,并将后半段链表逆置,对比两部分链表数据是否相同。包含以下5步:

  1. 定义两个指向链表头结点的指针slowPtr和fastPtr,以不同的速度向前移动,slowPtr每次移动1个结点,fastPtr每次移动两个结点;
  2. 当fastPtr移动到末尾时,slowPtr刚好指向中间结点;
  3. 从slowPtr的后继结点开始,逆置链表;
  4. 比较前半部分和后半部分的结点数据是否相同,若数据相同,则链表数据是回文;
  5. 还原后半部分链表数据。

    [!Tip] 需要注意链表结点数的奇偶性。若链表结点数是奇数,则要剔除掉中间结点进行比较

判断链表是否是回文.png


实现代码

【👉🏻>>点击展开查看代码】
        
/**  
 * 判定链表是否是回文  
 *  
 * @param headNode  
 * @author: Max Solider  
 * @date: 2022/10/11 22:39  
 */
 boolean isPalindromeList(NormalListNode headNode) {  
    if (headNode == null || headNode.getNext() == null || headNode.getNext() == headNode) {  
        System.out.println("The linked list is palindrome list.");  
        return true;    }  
    // 先找到中间结点  
    NormalListNode slowPtr = headNode;  
    NormalListNode fastPtr = headNode;  
    while (fastPtr.getNext() != null && fastPtr.getNext().getNext() != null) {  
        fastPtr = fastPtr.getNext().getNext();  
        slowPtr = slowPtr.getNext();  
    }  
    // 逆置后半部分链表  
    NormalListNode secondHalf = reverseList(slowPtr.getNext());  
    NormalListNode firstHalf = headNode;  
    NormalListNode secondHalfHead = secondHalf;  
    boolean palindrome = false;  
    // 因为链表长度可能是奇数,前半部分可能会比后半部分多一个数据,所以用后半部分的长度来遍历  
    while (secondHalf != null) {  
        if (secondHalf.getData() != firstHalf.getData()) {  
            break;  
        }  
        secondHalf = secondHalf.getNext();  
        firstHalf = firstHalf.getNext();  
    }  
    if (palindrome) {  
        System.out.println("The linked list is palindrome list.");  
    } else {  
        System.out.println("The lined list is not palindrome list.");  
    }  
    // 还原后半部分链表  
    reverseList(secondHalfHead);  
    listLength(headNode);  
    return true;}  

/**  
 * 逆置链表  
 *  
 * @author: Max Solider  
 * @date: 2022/10/11 23:26  
 * @param headNode  
 * @return org.example.linkedlist.normal.NormalListNode  
 */
 NormalListNode reverseList(NormalListNode headNode) {  
    if (headNode == null || headNode.getNext() == null) {  
        return headNode;  
    }  
    NormalListNode current = headNode;  
    NormalListNode previous = null;  
    while (current != null) {  
        NormalListNode temp = current.getNext();  
        current.setNext(previous);  
        previous = current;  
        current = temp;  
    }  
    return previous;  
}
        
    

时间复杂度

时间复杂度为O(n),用于遍历链表。


空间复杂度

空间复杂度为O(1),用于存储临时变量。


© MaxSolider all right reserved,powered by Gitbook文件修订时间: 2022-10-12 23:31:16

results matching ""

    No results matching ""