[LeetCode] #234 回文链表

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

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

输出:true

回文相关题目:

[LeetCode] #125 验证回文串

[LeetCode] #9 回文数

[LeetCode] #7 整数反转

对于回文题目,通常使用反转法和双指针法

双指针法对于没有序号的链表需要先转换为有序号的数组

class Solution {
    public boolean isPalindrome(ListNode head) {
        List<Integer> list = new ArrayList<Integer>();
        ListNode p1 = head;
        while (p1 != null) {
            list.add(p1.val);
            p1 = p1.next;
        }
        int left = 0;
        int right = list.size() - 1;
        while (left < right) {
            if (!list.get(left).equals(list.get(right))) return false;
            left++;
            right--;
        }
        return true;
    }
}

反转法,需要反转链表  为了不使用额外的空间可以只反转后半部分

为此需要找到前半部分链表的尾节点、反转后半部分链表、判断是否回文、恢复链表、返回结果

class Solution {
    public boolean isPalindrome(ListNode head) {
        if (head == null) return true;

        ListNode firstHalfEnd = endOfFirstHalf(head);
        ListNode secondHalfStart = reverseList(firstHalfEnd.next);

        ListNode p1 = head;
        ListNode p2 = secondHalfStart;
        boolean result = true;
        while (result && p2 != null) {
            if (p1.val != p2.val) {
                result = false;
            }
            p1 = p1.next;
            p2 = p2.next;
        }        

        firstHalfEnd.next = reverseList(secondHalfStart);
        return result;
    }

    private ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode nextTemp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }

    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;
    }
}

递归,使用辅助指针保留头节点。递归到尾节点,不断返回,不断往中间比较

class Solution {
    private ListNode frontPointer;

    private boolean recursivelyCheck(ListNode currentNode) {
        if (currentNode != null) {
            if (!recursivelyCheck(currentNode.next)) return false;
            if (currentNode.val != frontPointer.val) return false;
            frontPointer = frontPointer.next;
        }
        return true;
    }
    
    public boolean isPalindrome(ListNode head) {
        frontPointer = head;
        return recursivelyCheck(head);
    }
}

知识点:

总结:

posted @ 2021-09-14 10:24  1243741754  阅读(25)  评论(0编辑  收藏  举报