Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 51k
Add DocTests to is_palindrome.py#10081
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
9c16d06de9280c1e9a24c8e984f18923970e92c9e6dd72ef83808ddc6b5629a2299c0f3206174331ca32File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,65 +1,167 @@ | ||||||||||||||||||
| def is_palindrome(head): | ||||||||||||||||||
| from __future__ import annotations | ||||||||||||||||||
| from dataclasses import dataclass | ||||||||||||||||||
| @dataclass | ||||||||||||||||||
| class ListNode: | ||||||||||||||||||
SaiHarshaK marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||||||||||||||||||
| val: int = 0 | ||||||||||||||||||
| next_node: ListNode | None = None | ||||||||||||||||||
| def is_palindrome(head: ListNode | None) -> bool: | ||||||||||||||||||
| """ | ||||||||||||||||||
| Check if a linked list is a palindrome. | ||||||||||||||||||
| Args: | ||||||||||||||||||
| head: The head of the linked list. | ||||||||||||||||||
| Returns: | ||||||||||||||||||
| bool: True if the linked list is a palindrome, False otherwise. | ||||||||||||||||||
| Examples: | ||||||||||||||||||
| >>> is_palindrome(None) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome(ListNode(1)) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome(ListNode(1, ListNode(2))) | ||||||||||||||||||
| False | ||||||||||||||||||
| >>> is_palindrome(ListNode(1, ListNode(2, ListNode(1)))) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome(ListNode(1, ListNode(2, ListNode(2, ListNode(1))))) | ||||||||||||||||||
| True | ||||||||||||||||||
| """ | ||||||||||||||||||
| if not head: | ||||||||||||||||||
| return True | ||||||||||||||||||
| # split the list to two parts | ||||||||||||||||||
| fast, slow = head.next, head | ||||||||||||||||||
| while fast and fast.next: | ||||||||||||||||||
| fast = fast.next.next | ||||||||||||||||||
| slow = slow.next | ||||||||||||||||||
| second = slow.next | ||||||||||||||||||
| slow.next = None # Don't forget here! But forget still works! | ||||||||||||||||||
| fast: ListNode | None = head.next_node | ||||||||||||||||||
| slow: ListNode | None = head | ||||||||||||||||||
| while fast and fast.next_node: | ||||||||||||||||||
| fast = fast.next_node.next_node | ||||||||||||||||||
| slow = slow.next_node if slow else None | ||||||||||||||||||
| if slow: | ||||||||||||||||||
| # slow will always be defined, | ||||||||||||||||||
| # adding this check to resolve mypy static check | ||||||||||||||||||
| second = slow.next_node | ||||||||||||||||||
| slow.next_node = None # Don't forget here! But forget still works! | ||||||||||||||||||
| # reverse the second part | ||||||||||||||||||
| node = None | ||||||||||||||||||
| node: ListNode | None = None | ||||||||||||||||||
| while second: | ||||||||||||||||||
| nxt = second.next | ||||||||||||||||||
| second.next = node | ||||||||||||||||||
| nxt = second.next_node | ||||||||||||||||||
| second.next_node = node | ||||||||||||||||||
| node = second | ||||||||||||||||||
| second = nxt | ||||||||||||||||||
| # compare two parts | ||||||||||||||||||
| # second part has the same or one less node | ||||||||||||||||||
| while node: | ||||||||||||||||||
| while node and head: | ||||||||||||||||||
| if node.val != head.val: | ||||||||||||||||||
| return False | ||||||||||||||||||
| node = node.next | ||||||||||||||||||
| head = head.next | ||||||||||||||||||
| node = node.next_node | ||||||||||||||||||
| head = head.next_node | ||||||||||||||||||
SaiHarshaK marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||||||||||||||||||
| return True | ||||||||||||||||||
| def is_palindrome_stack(head): | ||||||||||||||||||
| if not head or not head.next: | ||||||||||||||||||
| def is_palindrome_stack(head: ListNode | None) -> bool: | ||||||||||||||||||
| """ | ||||||||||||||||||
| Check if a linked list is a palindrome using a stack. | ||||||||||||||||||
| Args: | ||||||||||||||||||
| head (ListNode): The head of the linked list. | ||||||||||||||||||
| Returns: | ||||||||||||||||||
| bool: True if the linked list is a palindrome, False otherwise. | ||||||||||||||||||
| Examples: | ||||||||||||||||||
| >>> is_palindrome_stack(None) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome_stack(ListNode(1)) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome_stack(ListNode(1, ListNode(2))) | ||||||||||||||||||
| False | ||||||||||||||||||
| >>> is_palindrome_stack(ListNode(1, ListNode(2, ListNode(1)))) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome_stack(ListNode(1, ListNode(2, ListNode(2, ListNode(1))))) | ||||||||||||||||||
| True | ||||||||||||||||||
| """ | ||||||||||||||||||
| if not head or not head.next_node: | ||||||||||||||||||
| return True | ||||||||||||||||||
| # 1. Get the midpoint (slow) | ||||||||||||||||||
| slow = fast = cur = head | ||||||||||||||||||
| while fast and fast.next: | ||||||||||||||||||
| fast, slow = fast.next.next, slow.next | ||||||||||||||||||
| # 2. Push the second half into the stack | ||||||||||||||||||
| stack = [slow.val] | ||||||||||||||||||
| while slow.next: | ||||||||||||||||||
| slow = slow.next | ||||||||||||||||||
| stack.append(slow.val) | ||||||||||||||||||
| # 3. Comparison | ||||||||||||||||||
| while stack: | ||||||||||||||||||
| if stack.pop() != cur.val: | ||||||||||||||||||
| return False | ||||||||||||||||||
| cur = cur.next | ||||||||||||||||||
| slow: ListNode | None = head | ||||||||||||||||||
| fast: ListNode | None = head | ||||||||||||||||||
| while fast and fast.next_node: | ||||||||||||||||||
| fast = fast.next_node.next_node | ||||||||||||||||||
| slow = slow.next_node if slow else None | ||||||||||||||||||
| # slow will always be defined, | ||||||||||||||||||
| # adding this check to resolve mypy static check | ||||||||||||||||||
| if slow: | ||||||||||||||||||
| stack = [slow.val] | ||||||||||||||||||
| # 2. Push the second half into the stack | ||||||||||||||||||
| while slow.next_node: | ||||||||||||||||||
| slow = slow.next_node | ||||||||||||||||||
| stack.append(slow.val) | ||||||||||||||||||
| # 3. Comparison | ||||||||||||||||||
| cur: ListNode | None = head | ||||||||||||||||||
| while stack and cur: | ||||||||||||||||||
| if stack.pop() != cur.val: | ||||||||||||||||||
| return False | ||||||||||||||||||
| cur = cur.next_node | ||||||||||||||||||
| return True | ||||||||||||||||||
| def is_palindrome_dict(head): | ||||||||||||||||||
| if not head or not head.next: | ||||||||||||||||||
| def is_palindrome_dict(head: ListNode | None) -> bool: | ||||||||||||||||||
| """ | ||||||||||||||||||
| Check if a linked list is a palindrome using a dictionary. | ||||||||||||||||||
| Args: | ||||||||||||||||||
| head (ListNode): The head of the linked list. | ||||||||||||||||||
| Returns: | ||||||||||||||||||
| bool: True if the linked list is a palindrome, False otherwise. | ||||||||||||||||||
| Examples: | ||||||||||||||||||
| >>> is_palindrome_dict(None) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome_dict(ListNode(1)) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome_dict(ListNode(1, ListNode(2))) | ||||||||||||||||||
| False | ||||||||||||||||||
| >>> is_palindrome_dict(ListNode(1, ListNode(2, ListNode(1)))) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome_dict(ListNode(1, ListNode(2, ListNode(2, ListNode(1))))) | ||||||||||||||||||
| True | ||||||||||||||||||
| >>> is_palindrome_dict(\ | ||||||||||||||||||
| ListNode(\ | ||||||||||||||||||
| 1, ListNode(2, ListNode(1, ListNode(3, ListNode(2, ListNode(1))))))) | ||||||||||||||||||
Comment on lines
+150
to
+152
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PEP8 discourages backslash line termination in Python because any whitespace to the right of the backslash breaks the script on a change that is invisible to the reader. Also, backslashes are not required inside of (), [], {}...
Suggested change
ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ruff complains that the length of the line is >88 which is why I had to split them into multiple lines. If i do not add backslash, DocTest assumes Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You needed the three dots at the beginning of each continued line as discussed in the doctest docs. | ||||||||||||||||||
| False | ||||||||||||||||||
| """ | ||||||||||||||||||
| if not head or not head.next_node: | ||||||||||||||||||
| return True | ||||||||||||||||||
| d = {} | ||||||||||||||||||
| d: dict[int, list[int]] = {} | ||||||||||||||||||
| pos = 0 | ||||||||||||||||||
| while head: | ||||||||||||||||||
| if head.val in d: | ||||||||||||||||||
| d[head.val].append(pos) | ||||||||||||||||||
| else: | ||||||||||||||||||
| d[head.val] = [pos] | ||||||||||||||||||
| head = head.next | ||||||||||||||||||
| head = head.next_node | ||||||||||||||||||
| pos += 1 | ||||||||||||||||||
| checksum = pos - 1 | ||||||||||||||||||
| middle = 0 | ||||||||||||||||||
| @@ -75,3 +177,9 @@ def is_palindrome_dict(head): | ||||||||||||||||||
| if middle > 1: | ||||||||||||||||||
| return False | ||||||||||||||||||
| return True | ||||||||||||||||||
| if __name__ == "__main__": | ||||||||||||||||||
| import doctest | ||||||||||||||||||
| doctest.testmod() | ||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.