forked from wangzheng0822/algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b86cd91
commit a04b592
Showing
1 changed file
with
92 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
""" | ||
1) Reverse singly-linked list | ||
2) Detect cycle in a list | ||
3) Merge two sorted lists | ||
4) Remove nth node from the end | ||
5) Find middle node | ||
Author: Wenru | ||
""" | ||
|
||
from typing import Optional | ||
|
||
|
||
class Node: | ||
|
||
def __init__(self, data: int, next=None): | ||
self.data = data | ||
self._next = next | ||
|
||
# Reverse singly-linked list | ||
# 单链表反转 | ||
# Note that the input is assumed to be a Node, not a linked list. | ||
def reverse(head: Node) -> Optional[Node]: | ||
reversed_head = None | ||
current = head | ||
while current: | ||
reversed_head, reversed_head._next, current = current, reversed_head, current._next | ||
return reversed_head | ||
|
||
# Detect cycle in a list | ||
# 检测环 | ||
def has_cycle(head: Node) -> bool: | ||
slow, fast = head, head | ||
while fast and fast._next: | ||
slow = slow._next | ||
fast = fast._next._next | ||
if slow == fast: | ||
return True | ||
return False | ||
|
||
# Merge two sorted linked list | ||
# 有序链表合并 | ||
def merge_sorted_list(l1: Node, l2: Node) -> Optional[Node]: | ||
if l1 and l2: | ||
p1, p2 = l1, l2 | ||
fake_head = Node(None) | ||
current = fake_head | ||
while p1 and p2: | ||
if p1.data <= p2.data: | ||
current._next = p1 | ||
p1 = p1._next | ||
else: | ||
current._next = p2 | ||
p2 = p2._next | ||
current = current._next | ||
current._next = p1 if p1 else p2 | ||
return fake_head._next | ||
return p1 or p2 | ||
|
||
# Remove nth node from the end | ||
# 删除倒数第n个节点。假设n大于0 | ||
def remove_nth_from_end(head: Node, n: int) -> Optional[Node]: | ||
fast = head | ||
count = 0 | ||
while fast and count < n: | ||
fast = fast._next | ||
count += 1 | ||
if not fast and count < n: # not that many nodes | ||
return head | ||
if not fast and count == n: | ||
return head._next | ||
|
||
slow = head | ||
while fast._next: | ||
fast, slow = fast._next, slow._next | ||
slow._next = slow._next._next | ||
return head | ||
|
||
def find_middle_node(head: Node) -> Optional[Node]: | ||
slow, fast = head, head | ||
fast = fast._next if fast else None | ||
while fast and fast._next: | ||
slow, fast = slow._next, fast._next._next | ||
return slow | ||
|
||
def print_all(head: Node): | ||
nums = [] | ||
current = head | ||
while current: | ||
nums.append(current.data) | ||
current = current._next | ||
print("->".join(str(num) for num in nums)) |