-
-
Notifications
You must be signed in to change notification settings - Fork 46.8k
[NEW ALGORITHM] Rotate linked list by K. #9278
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
Changes from 6 commits
6e610d4
6122ded
64e0196
a8058ad
edfd0ec
1b9e7da
e04ed07
589cb8c
c0a1f8e
34260bf
b575263
0644ed0
69e4ddb
69aa9fe
5439cea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,147 @@ | ||||||||||||||||||||||||||||||||||||||||||||
from __future__ import annotations | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
class Node: | ||||||||||||||||||||||||||||||||||||||||||||
def __init__(self, data: int) -> None: | ||||||||||||||||||||||||||||||||||||||||||||
self.data = data | ||||||||||||||||||||||||||||||||||||||||||||
self.next = None | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
def print_linked_list(head: Node | None) -> None: | ||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||
Print the entire linked list iteratively. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
This function prints the elements of a linked list iteratively, separated by '->'. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Parameters: | ||||||||||||||||||||||||||||||||||||||||||||
head (Node | None): The head of the linked list to be printed, | ||||||||||||||||||||||||||||||||||||||||||||
or None if the linked list is empty. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
>>> head = None | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 0) | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 2) | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 1) | ||||||||||||||||||||||||||||||||||||||||||||
>>> print_linked_list(head) | ||||||||||||||||||||||||||||||||||||||||||||
0->2->1 | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 4) | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 5) | ||||||||||||||||||||||||||||||||||||||||||||
>>> print_linked_list(head) | ||||||||||||||||||||||||||||||||||||||||||||
0->2->1->4->5 | ||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||
if head is None: | ||||||||||||||||||||||||||||||||||||||||||||
return | ||||||||||||||||||||||||||||||||||||||||||||
while head.next is not None: | ||||||||||||||||||||||||||||||||||||||||||||
print(head.data, end="->") | ||||||||||||||||||||||||||||||||||||||||||||
head = head.next | ||||||||||||||||||||||||||||||||||||||||||||
print(head.data) | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
def insert_node(head: Node | None, data: int) -> Node: | ||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||
Insert a new node at the end of a linked list and return the new head. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Parameters: | ||||||||||||||||||||||||||||||||||||||||||||
head (Node | None): The head of the linked list. | ||||||||||||||||||||||||||||||||||||||||||||
data (int): The data to be inserted into the new node. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||
Node: The new head of the linked list. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
>>> head = None | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 10) | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 9) | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 8) | ||||||||||||||||||||||||||||||||||||||||||||
>>> print_linked_list(head) | ||||||||||||||||||||||||||||||||||||||||||||
10->9->8 | ||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||
new_node = Node(data) | ||||||||||||||||||||||||||||||||||||||||||||
# If the linked list is empty, the new_node becomes the head | ||||||||||||||||||||||||||||||||||||||||||||
if head is None: | ||||||||||||||||||||||||||||||||||||||||||||
return new_node | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
temp_node = head | ||||||||||||||||||||||||||||||||||||||||||||
while temp_node.next is not None: | ||||||||||||||||||||||||||||||||||||||||||||
temp_node = temp_node.next | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
temp_node.next = new_node # type: ignore | ||||||||||||||||||||||||||||||||||||||||||||
return head | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
def right_rotate_by_k(head: Node | None, rotation: int) -> Node | None: | ||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||
Rotate a linked list to the right by rotation times. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Parameters: | ||||||||||||||||||||||||||||||||||||||||||||
head (Node | None): The head of the linked list. | ||||||||||||||||||||||||||||||||||||||||||||
rotation (int): The number of places to rotate. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||
Node | None: The head of the rotated linked list\ | ||||||||||||||||||||||||||||||||||||||||||||
if the linked list is not None, otherwise None. | ||||||||||||||||||||||||||||||||||||||||||||
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. Mypy can test data types in the function signature, but not in the comments. Do not repeat the datatypes in both places because readers will be confused if one is changed and the other is not. How about this naming...
Suggested change
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. I might even raise a 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. Do we have a test for a linked list that has just 3 elements but we are asked to shift to the right 10 places? 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. What happens if we are asked to shift to the right -2 places? -2.5 places? 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.
If the rotation number is not an integer, it should raise an error. If it is a negative integer, converting it to a positive integer would be a better idea, right? 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.
Yes, I tested it, and it is working correctly. |
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
>>> head = None | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 1) | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 2) | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 3) | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 4) | ||||||||||||||||||||||||||||||||||||||||||||
>>> head = insert_node(head, 5) | ||||||||||||||||||||||||||||||||||||||||||||
>>> rotation = 2 | ||||||||||||||||||||||||||||||||||||||||||||
>>> new_head = right_rotate_by_k(head, rotation) | ||||||||||||||||||||||||||||||||||||||||||||
>>> print_linked_list(new_head) | ||||||||||||||||||||||||||||||||||||||||||||
4->5->1->2->3 | ||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||
# Check if the list is empty or has only one element | ||||||||||||||||||||||||||||||||||||||||||||
if head is None or head.next is None: | ||||||||||||||||||||||||||||||||||||||||||||
return head | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
# Calculate the length of the linked list | ||||||||||||||||||||||||||||||||||||||||||||
length = 1 | ||||||||||||||||||||||||||||||||||||||||||||
temp_node = head | ||||||||||||||||||||||||||||||||||||||||||||
while temp_node.next is not None: | ||||||||||||||||||||||||||||||||||||||||||||
length += 1 | ||||||||||||||||||||||||||||||||||||||||||||
temp_node = temp_node.next | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
# Adjust the value of rotation to avoid unnecessary rotations. | ||||||||||||||||||||||||||||||||||||||||||||
rotation %= length | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if rotation == 0: | ||||||||||||||||||||||||||||||||||||||||||||
return head # As No rotation needed. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
# Find the new head position after rotation. | ||||||||||||||||||||||||||||||||||||||||||||
new_head_index = length - rotation | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
# Traverse to the new head position | ||||||||||||||||||||||||||||||||||||||||||||
temp_node = head | ||||||||||||||||||||||||||||||||||||||||||||
for _ in range(new_head_index - 1): | ||||||||||||||||||||||||||||||||||||||||||||
temp_node = temp_node.next | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
# Update pointers to perform rotation | ||||||||||||||||||||||||||||||||||||||||||||
new_head = temp_node.next | ||||||||||||||||||||||||||||||||||||||||||||
temp_node.next = None | ||||||||||||||||||||||||||||||||||||||||||||
temp_node = new_head | ||||||||||||||||||||||||||||||||||||||||||||
while temp_node.next is not None: | ||||||||||||||||||||||||||||||||||||||||||||
temp_node = temp_node.next | ||||||||||||||||||||||||||||||||||||||||||||
temp_node.next = head | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
return new_head | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if __name__ == "__main__": | ||||||||||||||||||||||||||||||||||||||||||||
import doctest | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
doctest.testmod() | ||||||||||||||||||||||||||||||||||||||||||||
head = None | ||||||||||||||||||||||||||||||||||||||||||||
head = insert_node(head, 5) | ||||||||||||||||||||||||||||||||||||||||||||
head = insert_node(head, 1) | ||||||||||||||||||||||||||||||||||||||||||||
head = insert_node(head, 2) | ||||||||||||||||||||||||||||||||||||||||||||
head = insert_node(head, 4) | ||||||||||||||||||||||||||||||||||||||||||||
head = insert_node(head, 3) | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
print("Original list: ", end="") | ||||||||||||||||||||||||||||||||||||||||||||
print_linked_list(head) | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
k = 3 | ||||||||||||||||||||||||||||||||||||||||||||
new_head = right_rotate_by_k(head, k) | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
print("After", k, "iterations: ", end="") | ||||||||||||||||||||||||||||||||||||||||||||
print_linked_list(new_head) |
Uh oh!
There was an error while loading. Please reload this page.