Skip to content

Commit 1029696

Browse files
author
wuduhren
committed
Updates
1 parent 612e17e commit 1029696

6 files changed

+175
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""
2+
Time: O(N)
3+
Space: O(1)
4+
5+
The easiest way would be maintaining a hash map for original node to the copy and the other way around. Then the rest is easy.
6+
But this will take us O(N) of extra space.
7+
8+
Two pass solution with constant space.
9+
First pass.
10+
Create a copy of the original and store it inside "random".
11+
The copy points to original's next and original's random.
12+
13+
Second pass.
14+
Iterate through the nodes again.
15+
This time we adjust the copy to point to the other copies.
16+
"""
17+
class Solution:
18+
def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
19+
if not head: return head
20+
21+
node = head
22+
while node:
23+
copy = Node(node.val, node.next, node.random)
24+
node.random = copy
25+
node = node.next
26+
27+
node = head
28+
while node:
29+
newNode = node.random
30+
if node.next: newNode.next = node.next.random
31+
if newNode.random: newNode.random = newNode.random.random
32+
node = node.next
33+
34+
return head.random
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""
2+
[0] For each height, if the it is lower than the previous one, it means that the previous are not able to extend anymore. So we calculate its area.
3+
4+
[1] If the previous area, is larger than the current one, it means that the current one are able to extand backward.
5+
"""
6+
class Solution:
7+
def largestRectangleArea(self, heights: List[int]) -> int:
8+
maxArea = 0
9+
stack = []
10+
11+
heights.append(0) #dummy for the ending
12+
13+
for i, h in enumerate(heights):
14+
start = i
15+
while stack and h<stack[-1][1]: #[0]
16+
j, h2 = stack.pop()
17+
maxArea = max(maxArea, h2*(i-j))
18+
start = j
19+
stack.append((start, h)) #[1]
20+
21+
return maxArea
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Solution:
2+
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
3+
head = ListNode() #dummy
4+
node = head
5+
while list1 and list2:
6+
if list1.val<list2.val:
7+
node.next = list1
8+
list1 = list1.next
9+
else:
10+
node.next = list2
11+
list2 = list2.next
12+
node = node.next
13+
14+
node.next = list1 or list2
15+
return head.next
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#Two pass.
2+
class Solution:
3+
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
4+
#count the length of the linked list
5+
node = head
6+
count = 0
7+
while node:
8+
count += 1
9+
node = node.next
10+
11+
12+
node = head
13+
steps = count-n-1
14+
15+
#steps==-1 means that we need to remove the first node
16+
if steps==-1: return head.next
17+
18+
#traverse to the node before the node we wanted to remove
19+
while steps>0:
20+
node = node.next
21+
steps -= 1
22+
23+
#remove "node.next"
24+
node.next = node.next.next
25+
26+
return head
27+
28+
29+
#One pass. Fast pointer is ahead of slow pointer by n+1
30+
#So slow pointer will stop at the node before the node we wanted to remove
31+
class Solution:
32+
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
33+
dummy = ListNode()
34+
dummy.next = head
35+
36+
ahead = n+1
37+
fast = dummy
38+
slow = dummy
39+
40+
while fast:
41+
fast = fast.next
42+
ahead -= 1
43+
if ahead<0: slow = slow.next
44+
45+
slow.next = slow.next.next
46+
47+
return dummy.next

problems/python3/reorder-list.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class Solution:
2+
def reorderList(self, head: Optional[ListNode]) -> None:
3+
#find the middle point
4+
slow = head
5+
fast = head
6+
while fast and fast.next:
7+
slow = slow.next
8+
fast = fast.next.next
9+
middle = slow.next
10+
11+
#reverse the linked list after the middle point
12+
middle = self.reverseList(middle)
13+
14+
#separate the linked list before the middle
15+
slow.next = None
16+
17+
#merge two linked list
18+
node = head
19+
while middle and node:
20+
nextNode = node.next
21+
node.next = middle
22+
middle = middle.next
23+
node.next.next = nextNode
24+
node = nextNode
25+
return head
26+
27+
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
28+
pre = None
29+
node = head
30+
31+
while node:
32+
nextNode = node.next
33+
node.next = pre
34+
if not nextNode: return node
35+
pre = node
36+
node = nextNode
37+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#Recursive
2+
class Solution:
3+
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
4+
if not head or not head.next: return head
5+
temp = self.reverseList(head.next)
6+
head.next.next = head
7+
head.next = None
8+
return temp
9+
10+
#Iterative
11+
class Solution:
12+
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
13+
pre = None
14+
node = head
15+
16+
while node:
17+
nextNode = node.next
18+
node.next = pre
19+
if not nextNode: return node
20+
pre = node
21+
node = nextNode

0 commit comments

Comments
 (0)