判断回文链表

问题描述

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false

实现思路

  1. 设置快慢指针
  2. 慢指针一次前进一个节点,快指针一次前进两个节点,当快指针前进到最后一个节点时,慢指针刚好到前一半链表的最后一个。通过这种方法找到前一半链表的最后一个节点。
  3. 将后一半链表反转后与前一半链表对比相同即是回文链表。
  4. 注意最后将反转的链表反转复原。

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    //找到前半部分链表的最后节点
    private ListNode endOfFirstHalf (ListNode head){
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
    //反转后半部分链表
    private ListNode reverseListNode (ListNode head){
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode nextTemp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }
    public boolean isPalindrome(ListNode head) {
        //判断是否为空链表,空链表是回文链表
        if (head == null) {
            return true;
        }

        //找到前半部分链表尾结点,反转后半部分
        ListNode firstHalfEnd = endOfFirstHalf(head);
        ListNode secondHalfStart = reverseListNode(firstHalfEnd.next);

        //判断是否回文
        ListNode p1 = head;
        ListNode p2 = secondHalfStart;

        boolean result = true;
        while (p2 != null) {
            if (p1.val != p2.val) {
                result = false;
            }
            p1 = p1.next;
            p2 = p2.next;
        }
        //还原链表
        firstHalfEnd.next = reverseListNode(secondHalfStart);
        return result;
    }
    /*
    执行耗时:6 ms,击败了52.00% 的Java用户
	内存消耗:51.1 MB,击败了91.39% 的Java用户
     */
}

你可能感兴趣的:(算法,算法)