链表的回文串问题

55 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目

给一个链表,判断它是不是回文串。

思路

我们先找到中点或者下中点,然后把后半部分翻转一下,然后一个指针从头开始,一个指针从后面开始,他们比较是否相等。

举例

1 -> 2 -> 3 -> 2 -> 1

我们先找到中点是3,之后就是翻转后半部分的链表

1 -> 2 -> 3 <- 2 <- 1

3最后会指向null

接下来来看代码吧

代码

节点类

public static class Node {
    public int value;
    public Node next;

    public Node(int data) {
        this.value = data;
    }
}

节点类可以先看一下。

调用方法

public static boolean isPalindrome(Node head) {
    if(head == null || head.next == null){
        return true;
    }
    boolean ans = false;
    Node mid = findMid(head);
    Node tail = reverse(mid);
    Node curHead = head;
    Node curTail = tail;
    while(curTail != null && curHead != null){
        if(curTail.value != curHead.value){
            break;
        }
        curTail = curTail.next;
        curHead = curHead.next;
    }
    if(curTail == null || curHead == null){
        ans = true;
    }
    reverse(tail);
    return ans;
}

上面代码需要注意的是,判断什么时候结束是关键,

还有就是怎么判断是不是回文串。我们这边用的是判断循环是否正常结束来看的。如果循环是正常结束的,那么就是说明是回文串,如果没有就说明不是。

还有一点就是逆置之后的链表是要还原回去的,要不然就会破坏结构,这个是不提倡的。

寻找中点的方法

public static Node findMid(Node head){
    Node fast = head;
    Node slow = head;
    while(fast != null && fast.next != null){
        fast = fast.next.next;
        slow = slow.next;
    }
    return slow;
}

寻找中点的方法是为了后面逆置方法做铺垫,因为只有找到中点之后才能逆置,要不然逆置会找不到方向,不知道从哪开始

逆置链表的方法

public static Node reverse(Node head){
    Node pre = null;
    Node next = head.next;
    while(next != null){
        head.next = pre;
        pre = head;
        head = next;
        next = head.next;
    }
    head.next = pre;
    return head;
}

逆置链表环节算是这个题目的精髓吧,这个还是挺重要的。而且我们还要记得返回逆置之后的头结点,要不然链表就找不到了。后面也无法比较