1+ # ============================================================
2+ # LeetCode 234. Palindrome Linked List
3+ # ============================================================
4+ #
5+ # Problem:
6+ # Given the head of a singly linked list, return True if it is
7+ # a palindrome, otherwise return False.
8+ #
9+ # ------------------------------------------------------------
10+ # Approach: Fast & Slow Pointer + Reverse Second Half
11+ # ------------------------------------------------------------
12+ #
13+ # Algorithm:
14+ #
15+ # 1. Find the middle of the linked list using two pointers.
16+ # - slow moves one step.
17+ # - fast moves two steps.
18+ #
19+ # 2. If the list has an odd number of nodes,
20+ # skip the middle node because it does not affect
21+ # palindrome comparison.
22+ #
23+ # 3. Reverse the second half of the linked list.
24+ #
25+ # 4. Compare the first half and the reversed second half.
26+ # - If any values differ -> return False.
27+ # - Otherwise return True.
28+ #
29+ # ------------------------------------------------------------
30+ # Example
31+ # ------------------------------------------------------------
32+ #
33+ # Input:
34+ #
35+ # 1 -> 2 -> 2 -> 1
36+ #
37+ # Step 1: Find Middle
38+ #
39+ # slow
40+ # |
41+ # 1 -> 2 -> 2 -> 1
42+ #
43+ # Step 2: Reverse Second Half
44+ #
45+ # First Half:
46+ # 1 -> 2
47+ #
48+ # Second Half:
49+ # 1 -> 2
50+ #
51+ # Step 3: Compare
52+ #
53+ # 1 == 1
54+ # 2 == 2
55+ #
56+ # Output:
57+ # True
58+ #
59+ # ------------------------------------------------------------
60+ # Dry Run (Odd Length)
61+ # ------------------------------------------------------------
62+ #
63+ # Input:
64+ #
65+ # 1 -> 2 -> 3 -> 2 -> 1
66+ #
67+ # Middle = 3
68+ #
69+ # Skip middle
70+ #
71+ # Reverse:
72+ #
73+ # 2 -> 1
74+ #
75+ # becomes
76+ #
77+ # 1 -> 2
78+ #
79+ # Compare:
80+ #
81+ # Left : 1 -> 2
82+ # Right: 1 -> 2
83+ #
84+ # Every node matches.
85+ #
86+ # Output:
87+ # True
88+ #
89+ # ------------------------------------------------------------
90+ # Time Complexity
91+ # ------------------------------------------------------------
92+ #
93+ # Finding Middle : O(n)
94+ # Reversing Half : O(n/2)
95+ # Comparing Halves : O(n/2)
96+ #
97+ # Total Time:
98+ # O(n)
99+ #
100+ # ------------------------------------------------------------
101+ # Space Complexity
102+ # ------------------------------------------------------------
103+ #
104+ # O(1)
105+ #
106+ # Only a few pointers are used.
107+ # No extra array or stack.
108+ #
109+ # ============================================================
110+
111+ # Definition for singly-linked list.
112+ # class ListNode:
113+ # def __init__(self, val=0, next=None):
114+ # self.val = val
115+ # self.next = next
116+
117+ class Solution :
118+ def isPalindrome (self , head : Optional [ListNode ]) -> bool :
119+
120+ # Empty list or single node is always a palindrome.
121+ if not head or not head .next :
122+ return True
123+
124+ # ----------------------------------------------------
125+ # Step 1: Find the middle of the linked list
126+ # ----------------------------------------------------
127+ fast = head
128+ slow = head
129+
130+ while fast and fast .next :
131+ slow = slow .next
132+ fast = fast .next .next
133+
134+ # If fast is not None, the list contains
135+ # an odd number of nodes.
136+ # Skip the middle node.
137+ if fast :
138+ slow = slow .next
139+
140+ # ----------------------------------------------------
141+ # Step 2: Reverse the second half
142+ # ----------------------------------------------------
143+ prev = None
144+
145+ while slow :
146+ nxt = slow .next
147+ slow .next = prev
148+ prev = slow
149+ slow = nxt
150+
151+ # ----------------------------------------------------
152+ # Step 3: Compare both halves
153+ # ----------------------------------------------------
154+ left = head
155+ right = prev
156+
157+ while right :
158+ if left .val != right .val :
159+ return False
160+
161+ left = left .next
162+ right = right .next
163+
164+ return True
0 commit comments