# 回文链表

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

示例 1:

img

输入:head = [1,2,2,1]
输出:true

示例 2:

img

输入:head = [1,2]
输出:false

提示:

  • 链表中节点数目在范围 [1, 105]
  • 0 <= Node.val <= 9

# 方法 1:快慢指针

思路分析

先找到链表的中间点:

  • 如果是偶数就是中间靠右的 2
1	2	2	1

找到中间点后我们将其后面的节点进行反转

# 中间节点后面的元素
2	1
# 进行反转
1	2

用反转后的链表跟原始链表进行逐一比较,如果这后半个链表遍历完了大家都相同那么就是 回文

# 原始链表
1	2	2	1
# 遍历,后面半个链表进行比较是否相同,相同就是 回文
1	2

如果是如下的链表的话,分析结果:

1	2	3	1

取中间值的后半个链表,然后进行反转

3	1
# 反转
1	3

进行比较,当比较 2 与 3 的时候结果不相同 返回 false 不是一个回文链表

1	2	3	1
1	3

如果链表是奇数的情况也是一样的,比如下面的分析结果:

1	2	3	2	1

取中间节点的后半个链表,然后进行反转

3	2	1
# 反转
1	2	3

比较 ,相同返回 true 是 回文链表

1	2	3	2	1
1	2	3

总结

  • 我们需要使用到,取链表中间节点,反转链表,判断是否是回文

代码

public boolean isPalindrome(ListNode head) {
       ListNode mid = mid(head);
       ListNode reverse = reverse(mid);
       while(reverse != null)
       {
          if(reverse.val != head.val)
          {
            return false;
          }
          reverse = reverse.next;
          head = head.next;
       }
       return true;
    }
    public ListNode mid(ListNode head)
    {
        ListNode p1 = head;
        ListNode p2 = head;
        while(p2 != null && p2.next != null)
        {
            p1 = p1.next;
            p2 = p2.next.next;
        }
        return p1;
    }
    public ListNode reverse(ListNode o1)
    {
      ListNode n1 = null;
      ListNode p = o1;
      while(p != null)
      {
        n1 = new ListNode(p.val, n1);
        p = p.next;
      }
      return n1;
    }

优化后的代码

public boolean isPalindrome(ListNode head) {
        ListNode p1 = head; // 慢指针
        ListNode p2 = head; // 快指针
        ListNode n1 = null; // 新链表
        ListNode o1 = head; // 旧链表
        // 快指针停止条件为 本身或者 next 为 null
        while(p2 != null && p2.next != null)
        {
            // 慢指针一次走一步
            p1 = p1.next;
            // 快指针一次走两步
            p2 = p2.next.next;
            // 反转链表
            o1.next = n1;
            n1 = o1; 
            o1 = p1; 
        }
        if(p2 != null) // 奇数,选取后一个节点
        {
          p1 = p1.next;
        }
        while(n1 != null)
        {
            if(n1.val != p1.val)
            {
                return false;
            }
            n1 = n1.next;
            p1 = p1.next;
        }
        return true;
    }