【LeetCode】第234题——回文链表(难度:简单)

【LeetCode】第234题——回文链表(难度:简单)

  • 题目描述
  • 解题思路
  • 代码详解
  • 注意点

题目描述

请判断一个链表是否为回文链表。

  1. 示例 1:
    输入: 1->2
    输出: false

  2. 示例 2:
    输入: 1->2->2->1
    输出: true

进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

使用快慢指针,快的步长为2,慢的步长为1,这样快指针遍历到链表末尾时,慢指针指向了列表中间。与此同时,慢指针在移动时并不仅仅做简单的后移,是一边后移一边反转遍历过的部分链表。这样慢指针在走到中间时,前半链表已被反转,如果是回文链表,那么前后半部分应该是一样的(链表元素个数为奇数个可以多考虑一步,这点会在代码详解中提到)。

代码详解

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
     
    public boolean isPalindrome(ListNode head) {
     
        if(head == null || head.next == null) {
     	// 链表为空或者只有一个元素,也算是回文链表
            return true;
        }
        ListNode fast = head;	// 快指针,步长为2
        ListNode slow = head;	// 慢指针,步长为1
        ListNode temp = head;	// 临时指针
        ListNode headd = head;	// 反转链表的末端指针,用于反转后链表的连接,实际上就是原链表的头指针
        while(fast != null && fast.next != null) {
     
            temp = slow.next;	// 临时指针记录下一个链表节点
            slow.next = head;	// 反转,就是当前slow节点的下一个节点为反转链表的头节点
            head = slow;		// slow节点成为反转链表的新头节点
            headd.next = temp;	// 反转链表与原始slow指针未遍历到的链表相连接

            slow = temp;		// slow已经变为反转链表的头节点了,因此不能用slow = slow.next
            fast = fast.next.next;	// 快指针步长为2
        }
        if(fast != null && fast.next == null) {
     	// 为了应对链表元素为奇数个的情况,其实只要把slow节点后移一个即可,就是越过正中间那个节点
            slow = slow.next;	// 这里为什么就可以用slow = slow.next?
            					// 因为上个while循环结束前已经通过slow = temp把slow节点移动至原链表slow未遍历到的链表开头了
        }
        while(slow != null) {
     	// 这时候便可以一个个地对val进行比较了,head是反转链表的头,slow是后半部分链表的头
            if(head.val != slow.val) {
     
                return false;	// 只要有一个元素不相等,直接返回false
            }
            head = head.next;
            slow = slow.next;
        }
        return true;
    }
}

注意点

  1. 注意奇偶个数个节点对所谓“中间节点”的影响。
  2. 此方法开辟的空间少,相较于开辟栈和列表的思路要好。
  3. 通过此题可以再回顾一下206题——反转链表,此题可以也直接调用那个方法。

你可能感兴趣的:(LeetCode题解,链表,指针,leetcode,java)