Skip to content

Commit 1d8b0bb

Browse files
committed
[easy] 234. Palindrome Linked List
1 parent f9bd97e commit 1d8b0bb

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

234.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
from typing import Optional
2+
import unittest
3+
4+
# Definition for singly-linked list.
5+
class ListNode:
6+
def __init__(self, val=0, next=None):
7+
self.val = val
8+
self.next = next
9+
10+
11+
class Solution:
12+
"""The intuiton of this problem is very simple:
13+
Create a new array and store the linked list data there
14+
use two pointer technique to find if the chars are the same from left and right moving at the same time.
15+
16+
17+
However, the problem states we cannot use additional store size to do it. How can we solve?
18+
19+
We can split the linked list in the middle then revert the second half and compare it with the
20+
list initing in the head.
21+
22+
1) Use flow and fast pointers
23+
2) When fast hit Null then slow is in the middle
24+
3) Revert the second half of LL (prev = None, current = slow).
25+
4) After reverting the `prev` will have the HEAD of the second half (reverted)
26+
5) Loop throught the nodes checking their values
27+
"""
28+
def isPalindrome(self, head: Optional[ListNode]) -> bool:
29+
slow, fast = head, head
30+
31+
while slow and fast and fast.next:
32+
slow = slow.next
33+
fast = fast.next.next
34+
35+
prev = None
36+
current = slow
37+
38+
while current:
39+
next_node = current.next
40+
current.next = prev
41+
prev = current
42+
current = next_node
43+
44+
left = head
45+
right = prev
46+
47+
while left and right:
48+
if right.val != left.val:
49+
return False
50+
51+
left = left.next
52+
right = right.next
53+
54+
return True
55+
56+
57+
class Tests(unittest.TestCase):
58+
def test_one(self):
59+
prev = ListNode()
60+
head = prev
61+
62+
for v in [1, 2, 2, 1]:
63+
n = ListNode(val=v)
64+
prev.next = n
65+
prev = n
66+
67+
68+
self.assertEqual(Solution().isPalindrome(head.next), True)
69+
70+
71+
def test_two(self):
72+
prev = ListNode()
73+
head = prev
74+
75+
for v in [1, 2, 3, 1]:
76+
n = ListNode(val=v)
77+
prev.next = n
78+
prev = n
79+
80+
81+
self.assertEqual(Solution().isPalindrome(head.next), False)
82+
83+
84+
def test_three(self):
85+
prev = ListNode()
86+
head = prev
87+
88+
for v in [0, 2, 1]:
89+
n = ListNode(val=v)
90+
prev.next = n
91+
prev = n
92+
93+
94+
self.assertEqual(Solution().isPalindrome(head.next), False)
95+
96+
97+
if __name__ == "__main__":
98+
unittest.main()

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
| 141.py | Fast and Slow pointers | <https://leetcode.com/problems/linked-list-cycle/description/> |
1212
| 167.py | Two pointers | <https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/> |
1313
| 219.py | Array / Sliding Window | <https://leetcode.com/problems/find-the-duplicate-number/> |
14+
| 234.py | Linked List / Fast and Slow | <https://leetcode.com/problems/palindrome-linked-list/> |
1415
| 287.py | Two pointers / Hash table | <https://leetcode.com/problems/find-the-duplicate-number/> |
1516
| 643.py | Array / Sliding Window | <https://leetcode.com/problems/maximum-average-subarray-i/> |
1617
| 876.py | Fast and Slow pointers | <https://leetcode.com/problems/middle-of-the-linked-list/> |

0 commit comments

Comments
 (0)