1. 程式人生 > 實用技巧 >234. 迴文連結串列(連結串列)

234. 迴文連結串列(連結串列)

1、題目描述:

https://leetcode-cn.com/problems/palindrome-linked-list/

請判斷一個連結串列是否為迴文連結串列。

示例 1:

輸入: 1->2
輸出: false
示例 2:

輸入: 1->2->2->1
輸出: true
進階:
你能否用O(n) 時間複雜度和 O(1) 空間複雜度解決此題?

2、思路:

(1)快慢指標找到中間節點

(2)反轉中間節點右側的連結串列

(3)對比右側和左側

(4)將右側鏈表反轉回來

3、程式碼:

public class _0234_迴文連結串列 {
    public boolean isPalindrome(ListNode head) {
        
if (head == null || head.next == null) return true; if (head.next.next == null) return head.val == head.next.val; // 找到中間節點 ListNode mid = middleNode(head); // 翻轉右半部分(中間節點的右邊部分) ListNode rHead = reverseList(mid.next); ListNode lHead = head; ListNode rOldHead
= rHead; // 從lHead、rHead出發,判斷是否為迴文連結串列 boolean result = true; while (rHead != null) { if (lHead.val != rHead.val) { result = false; break; } rHead = rHead.next; lHead = lHead.next; }
// 恢復右半部分(對右半部分再次翻轉) reverseList(rOldHead); return result; } /** * 找到中間節點(右半部分連結串列頭結點的前一個節點) * 比如 1>2>3>2>1中的3是中間節點 * 比如 1>2>2>1中左邊第一個2是中間節點 * @param head * @return */ private ListNode middleNode(ListNode head) { ListNode fast = head; ListNode slow = head; while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } return slow; } /** * 翻轉連結串列 * @param head 原連結串列的頭結點 * 比如原連結串列:1>2>3>4>null,翻轉之後是:4>3>2>1>null * @return 翻轉之後連結串列的頭結點(返回4) */ private ListNode reverseList(ListNode head) { ListNode newHead = null; while (head != null) { ListNode tmp = head.next; head.next = newHead; newHead = head; head = tmp; } return newHead; } public static void main(String[] args) { ListNode head = new ListNode(1); head.next = new ListNode(2); head.next.next = new ListNode(3); head.next.next.next = new ListNode(2); // head.next.next.next.next = new ListNode(1); System.out.println(head); _0234_迴文連結串列 obj = new _0234_迴文連結串列(); obj.isPalindrome(head); System.out.println(head); } }

。。