Skip to content

Commit a915576

Browse files
committed
D. J.:
- Added the leetcode problem and solution for 2, 19, 21, 61, 82, 86, 92, 138, 141 and 146
1 parent bdb3cc3 commit a915576

31 files changed

+803
-50
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<img src="https://img.shields.io/badge/tests-passed-brightgreen">
1616
</a>
1717
<a>
18-
<img src="https://img.shields.io/badge/coverage-97%25-brightgreen">
18+
<img src="https://img.shields.io/badge/coverage-96%25-brightgreen">
1919
</a>
2020
</h1>
2121
</div>
@@ -25,18 +25,25 @@ This repository contains awesome LeetCode problems and solutions written in Pyth
2525
## Leetcode Problems & Solutions 💻
2626

2727
- [1 Two Sum](https://leetcode.com/problems/two-sum/description/)
28+
- [2 Add Two Numbers](https://leetcode.com/problems/add-two-numbers/description/)
29+
- [19 Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/)
2830
- [20 Valid Parentheses](https://leetcode.com/problems/valid-parentheses/description/)
31+
- [21 Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/description/)
2932
- [26 Remove Duplicates from Sorted Array](https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/)
3033
- [27 Remove Element](https://leetcode.com/problems/remove-element/description/)
3134
- [45 Jump Game II](https://leetcode.com/problems/jump-game-ii/description/)
3235
- [49 Group Anagrams](https://leetcode.com/problems/group-anagrams/description/)
3336
- [55 Jump Game](https://leetcode.com/problems/jump-game/description/)
3437
- [56 Merge Intervals](https://leetcode.com/problems/merge-intervals/description/)
3538
- [57 Insert Interval](https://leetcode.com/problems/insert-interval/description/)
39+
- [61 Rotate List](https://leetcode.com/problems/rotate-list/description/)
3640
- [67 Add Binary](https://leetcode.com/problems/add-binary/description/)
3741
- [71 Simplify Path](https://leetcode.com/problems/simplify-path/description/)
3842
- [80 Remove Duplicates from Sorted Array II](https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/description/)
43+
- [82 Remove Duplicates from Sorted List II](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/description/)
44+
- [86 Partition List](https://leetcode.com/problems/partition-list/description/)
3945
- [88 Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/description/)
46+
- [92 Reverse Linked List II](https://leetcode.com/problems/reverse-linked-list-ii/description/)
4047
- [98 Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/description/)
4148
- [100 Same Tree](https://leetcode.com/problems/same-tree/description/)
4249
- [101 Symmetric Tree](https://leetcode.com/problems/symmetric-tree/description/)
@@ -54,6 +61,11 @@ This repository contains awesome LeetCode problems and solutions written in Pyth
5461
- [125 Valid Palindrome](https://leetcode.com/problems/valid-palindrome/description/)
5562
- [128 Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/description/)
5663
- [129 Sum Root to Leaf Numbers](https://leetcode.com/problems/sum-root-to-leaf-numbers/description/)
64+
- [136 Single Number](https://leetcode.com/problems/single-number/description/)
65+
- [137 Single Number II](https://leetcode.com/problems/single-number-ii/description/)
66+
- [138 Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/description/)
67+
- [141 Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/description/)
68+
- [146 LRU Cache](https://leetcode.com/problems/lru-cache/description/)
5769
- [150 Evaluate Reverse Polish Notation](https://leetcode.com/problems/evaluate-reverse-polish-notation/description/)
5870
- [155 Min Stack](https://leetcode.com/problems/min-stack/description/)
5971
- [169 Majority Element](https://leetcode.com/problems/majority-element/description/)

awesome_python_leetcode/_117_populating_next_right_pointers_in_each_node_II.py

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,77 @@
1-
from awesome_python_leetcode.tree import TreeNode
1+
from typing import List, Optional
2+
3+
4+
class TreeNode:
5+
"""Binary tree node with next pointers."""
6+
7+
def __init__(
8+
self,
9+
val: int = 0,
10+
left: Optional["TreeNode"] = None,
11+
right: Optional["TreeNode"] = None,
12+
next: Optional["TreeNode"] = None,
13+
):
14+
self.val = val
15+
self.left = left
16+
self.right = right
17+
self.next = next
18+
19+
def __eq__(self, other: List[int]) -> bool:
20+
"""Compare the pointers to the next node."""
21+
if self is None or other is None:
22+
return True
23+
24+
cur = self
25+
i = 0
26+
while i < len(other):
27+
if other[i] is None:
28+
if cur is not None:
29+
return False
30+
i += 1
31+
if i < len(other):
32+
cur = TreeNode.find(self, other[i])
33+
continue
34+
else:
35+
if cur.val != other[i]:
36+
return False
37+
i += 1
38+
cur = cur.next
39+
return True
40+
41+
@staticmethod
42+
def find(root: Optional["TreeNode"], val: int) -> Optional["TreeNode"]:
43+
"""Find a node with a given value."""
44+
if root is None:
45+
return None
46+
elif root.val == val:
47+
return root
48+
else:
49+
return TreeNode.find(root.left, val) or TreeNode.find(root.right, val)
50+
51+
@staticmethod
52+
def build(levelorder: List[int]) -> "TreeNode":
53+
"""Build a binary tree from levelorder traversal."""
54+
if not levelorder or levelorder[0] is None:
55+
return None
56+
root = TreeNode(levelorder[0])
57+
queue = [root]
58+
59+
i = 1
60+
while i < len(levelorder):
61+
node = queue.pop(0)
62+
63+
# Left child
64+
if i < len(levelorder) and levelorder[i] is not None:
65+
node.left = TreeNode(levelorder[i])
66+
queue.append(node.left)
67+
i += 1
68+
69+
# Right child
70+
if i < len(levelorder) and levelorder[i] is not None:
71+
node.right = TreeNode(levelorder[i])
72+
queue.append(node.right)
73+
i += 1
74+
return root
275

376

477
class Solution:
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
from typing import List, Optional, Tuple
2+
3+
4+
class Node:
5+
def __init__(self, x: int, next: "Node" = None, random: "Node" = None):
6+
self.val = int(x)
7+
self.next = next
8+
self.random = random
9+
10+
def __hash__(self):
11+
return hash(self.val)
12+
13+
def __eq__(self, other: "Node") -> bool:
14+
n1, n2 = self, other
15+
while n1 and n2:
16+
if n1.val != n2.val:
17+
return False
18+
elif n1.random is None and n2.random:
19+
return False
20+
elif n1.random and n2.random is None:
21+
return False
22+
elif n1.random and n2.random and n1.random.val != n2.random.val:
23+
return False
24+
n1, n2 = n1.next, n2.next
25+
if n1 is None and n2:
26+
return False
27+
if n1 and n2 is None:
28+
return False
29+
return True
30+
31+
@staticmethod
32+
def build(values: List[Tuple[int, Optional[int]]]) -> "Node":
33+
"""Build a singly-linked list."""
34+
if not values:
35+
return None
36+
37+
# Step 1: Create all nodes without setting random pointers
38+
nodes = [Node(x) for x, _ in values]
39+
40+
# Step 2: Set the `next` pointers
41+
for i in range(len(nodes) - 1):
42+
nodes[i].next = nodes[i + 1]
43+
44+
# Step 3: Set the `random` pointers
45+
for i, (_, random_index) in enumerate(values):
46+
if random_index is not None:
47+
nodes[i].random = nodes[random_index]
48+
49+
return nodes[0]
50+
51+
52+
class Solution:
53+
"""Base class for all LeetCode Problems."""
54+
55+
def copyRandomList(self, head: "Optional[Node]") -> "Optional[Node]":
56+
"""
57+
A linked list of length n is given such that each node contains an additional
58+
random pointer, which could point to any node in the list, or null.
59+
60+
Construct a deep copy of the list. The deep copy should consist of exactly n
61+
brand new nodes, where each new node has its value set to the value of its
62+
corresponding original node. Both the next and random pointer of the new nodes
63+
should point to new nodes in the copied list such that the pointers in the
64+
original list and copied list represent the same list state. None of the
65+
pointers in the new list should point to nodes in the original list.
66+
67+
For example, if there are two nodes X and Y in the original list, where
68+
X.random --> Y, then for the corresponding two nodes x and y in the copied
69+
list, x.random --> y.
70+
71+
Return the head of the copied linked list.
72+
73+
The linked list is represented in the input/output as a list of n nodes. Each
74+
node is represented as a pair of [val, random_index] where:
75+
- val: an integer representing Node.val
76+
- random_index: the index of the node (range from 0 to n-1) that the random
77+
pointer points to, or null if it does not point to any node.
78+
79+
Your code will only be given the head of the original linked list.
80+
"""
81+
oldToCopy = {None: None}
82+
83+
cur = head
84+
while cur:
85+
copy = Node(cur.val)
86+
oldToCopy[cur] = copy
87+
cur = cur.next
88+
89+
cur = head
90+
while cur:
91+
copy = oldToCopy[cur]
92+
copy.next = oldToCopy[cur.next]
93+
copy.random = oldToCopy[cur.random]
94+
cur = cur.next
95+
96+
return oldToCopy[head]
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from typing import List, Optional
2+
3+
4+
class ListNode:
5+
"""Singly-linked list node."""
6+
7+
def __init__(self, val: int = 0, next: Optional["ListNode"] = None):
8+
self.val = val
9+
self.next = next
10+
11+
def __eq__(self, other: "ListNode") -> bool:
12+
if self is None and other is None:
13+
return True
14+
elif self is None:
15+
return False
16+
elif other is None:
17+
return False
18+
else:
19+
return self.val == other.val and self.next == other.next
20+
21+
@staticmethod
22+
def build(values: List[int], pos: Optional[int] = None) -> "ListNode":
23+
"""Build a singly-linked list with cycle."""
24+
if not values:
25+
return None
26+
27+
i = 0
28+
prev, head, cycle = None, None, None
29+
for i, val in enumerate(values):
30+
if i == 0:
31+
head = ListNode(val=val)
32+
prev = head
33+
else:
34+
node = ListNode(val=val)
35+
prev.next = node
36+
prev = node
37+
38+
if pos is not None and i == pos:
39+
cycle = prev
40+
elif pos is not None and i == len(values) - 1:
41+
prev.next = cycle
42+
return head
43+
44+
45+
class Solution:
46+
"""Base class for all LeetCode Problems."""
47+
48+
def hasCycle(self, head: Optional[ListNode]) -> bool:
49+
"""
50+
Given head, the head of a linked list, determine if the linked list has a cycle
51+
in it.
52+
53+
There is a cycle in a linked list if there is some node in the list that can be
54+
reached again by continuously following the next pointer. Internally, pos is
55+
used to denote the index of the node that tail's next pointer is connected to.
56+
Note that pos is not passed as a parameter.
57+
58+
Return true if there is a cycle in the linked list. Otherwise, return false.
59+
"""
60+
i, j = head, head
61+
while j and j.next:
62+
i = i.next
63+
j = j.next.next
64+
if i is j:
65+
return True
66+
return False
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
class Node:
2+
def __init__(self, key, val, prev=None, next=None):
3+
self.key = key
4+
self.val = val
5+
self.prev = prev
6+
self.next = next
7+
8+
9+
class LRUCache:
10+
11+
def __init__(self, capacity: int):
12+
self.cap = capacity
13+
self.cache = {}
14+
15+
# left=LRU, right=MRU
16+
self.left, self.right = Node(0, 0), Node(0, 0)
17+
self.left.next, self.right.prev = self.right, self.left
18+
19+
def remove(self, node):
20+
# Remove node from list
21+
prev, nxt = node.prev, node.next
22+
prev.next, nxt.prev = nxt, prev
23+
24+
def insert(self, node):
25+
# Insert node at right
26+
prev, nxt = self.right.prev, self.right
27+
prev.next = nxt.prev = node
28+
node.next, node.prev = nxt, prev
29+
30+
def get(self, key: int) -> int:
31+
if key in self.cache:
32+
self.remove(self.cache[key])
33+
self.insert(self.cache[key])
34+
return self.cache[key].val
35+
return -1
36+
37+
def put(self, key: int, value: int) -> None:
38+
if key in self.cache:
39+
self.remove(self.cache[key])
40+
self.cache[key] = Node(key, value)
41+
self.insert(self.cache[key])
42+
43+
if len(self.cache) > self.cap:
44+
# Remove from the list and delete the LRU from the hashmap
45+
lru = self.left.next
46+
self.remove(lru)
47+
del self.cache[lru.key]
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from typing import Optional
2+
3+
from awesome_python_leetcode.list import ListNode
4+
5+
6+
class Solution:
7+
"""Base class for all LeetCode Problems."""
8+
9+
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
10+
"""
11+
Given the head of a linked list, remove the nth node from the end of the list
12+
and return its head.
13+
"""
14+
dummy = ListNode(0, head)
15+
left, right = dummy, head
16+
17+
while n > 0 and right:
18+
right = right.next
19+
n -= 1
20+
21+
while right:
22+
left = left.next
23+
right = right.next
24+
25+
left.next = left.next.next
26+
return dummy.next
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from typing import Optional
2+
3+
from awesome_python_leetcode.list import ListNode
4+
5+
6+
class Solution:
7+
"""Base class for all LeetCode Problems."""
8+
9+
def mergeTwoLists(
10+
self,
11+
list1: Optional[ListNode],
12+
list2: Optional[ListNode],
13+
) -> Optional[ListNode]:
14+
"""
15+
You are given the heads of two sorted linked lists list1 and list2.
16+
17+
Merge the two lists into one sorted list. The list should be made by splicing
18+
together the nodes of the first two lists.
19+
20+
Return the head of the merged linked list.
21+
"""
22+
if list1 is None and list2 is None:
23+
return None
24+
elif list1 is None:
25+
return ListNode(list2.val, self.mergeTwoLists(None, list2.next))
26+
elif list2 is None:
27+
return ListNode(list1.val, self.mergeTwoLists(list1.next, None))
28+
elif list1.val <= list2.val:
29+
return ListNode(list1.val, self.mergeTwoLists(list1.next, list2))
30+
else:
31+
return ListNode(list2.val, self.mergeTwoLists(list1, list2.next))

0 commit comments

Comments
 (0)