Skip to content

Commit

Permalink
Implement new problems
Browse files Browse the repository at this point in the history
  • Loading branch information
romarowski committed Mar 3, 2024
1 parent f7e7ea0 commit bbc96f2
Show file tree
Hide file tree
Showing 15 changed files with 448 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.venv/
*.swp
.ipynb_checkpoints/
*.pyc
40 changes: 40 additions & 0 deletions 03-binary_tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,43 @@ def height(node):
- Space: O($n$), we have n calls to ```height()```.


### 199. Binary Tree Right Side View

**Statement**: Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

**Approach**: Transverse the tree, keeping track of the rightmost node at each level. Return the list of rightmost nodes.

We will iterate thorugh the tree and each node needs to know:
1. What level am I at?
2. Is there any node at my level that is more to the right than me?
a. If no, add to right_side.

A way to answer 2. is to make sure that at each level; rightmost nodes are visited first.
This hints us to a do a **Breadth First Search** since we need to exhaust each level before moving to the next.

To visit rightmost nodes first, we just add them to the queue first.

The following tree shows the order that nodes will be visited using the previously mentioned logic.

<div align="center">

```mermaid
graph TD
A((1)) --> B((3))
A -->C((2))
B -->D((6))
B -->E((7))
C -->F((5))
C -->G((4))
```

</div>

Now, to keep track of the level we define the root as being at level 0 and any child nodes will always be at level=current_level+1.

**Complexity**:
- Time: $O(n)$: we visit each node in the tree at least once.
- Space: $O(1)$: no new data structures are created; we just go through the tree.



52 changes: 52 additions & 0 deletions binary_search/374_guess_number_higher_or_lower.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
374. Guess Number Higher or Lower
Easy
We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I will tell you whether the number I picked is
higher or lower than your guess.
You call a pre-defined API int guess(int num), which returns three possible
results:
-1: Your guess is higher than the number I picked (i.e. num > pick).
1: Your guess is lower than the number I picked (i.e. num < pick).
0: your guess is equal to the number I picked (i.e. num == pick).
Return the number that I picked.
"""
import math

def guess(num):
pick=6
if num > pick:
return -1
elif num < pick:
return 1
else:
return 0

def guessNumber(n):
myg = n//2
lb, ub = 1, n

while guess(myg) !=0:

if guess(myg) == 1:
lb = myg+1

if guess(myg) == -1:
ub = myg-1

myg = (lb+ub) // 2
return myg




if __name__ == '__main__':
n = 10
print(guessNumber(n)) # -> 6
44 changes: 44 additions & 0 deletions binary_tree/199_binary_tree_right_side_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
199. Binary Tree Right Side View
Medium
Given the root of a binary tree, imagine yourself standing on the right side of
it, return the values of the nodes you can see ordered from top to bottom.
"""

from collections import deque

# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right

def rightSideView(root):
q = deque([])
level = 0
right_side = []

if root is None:
return []

#right_side = {
# level : root.val
#}

q.appendleft(root)

while q:
current = q.pop()
if level ==len(right_side):
right_side.append(current.val)

if current.right != None:
q.appendleft(current.right)

if current.left != None:
q.appendleft(current.left)

return right_side
19 changes: 19 additions & 0 deletions dynamic_programming/shortest_trips.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
From amazon OA.
Given a number n, and only two operations, -2 and -3, find the shortest
number of operations to reach 0.
Example:
n = 10
output = 5
10 - 3 = 7
7 - 3 = 4
4 - 2 = 2
2 - 2 = 0
"""


def shortest_trips(n):
pass

23 changes: 23 additions & 0 deletions dynamic_programming/tests/test_shortest_trips.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import unittest as ut
from dynamic_programming.shortest_trips import shortest_trips

class TestShortestTrips(ut.TestCase):
def test_shortest_trips(self):
n = 5
expected_output = 2
self.assertEqual(shortest_trips(n), expected_output)

def test_zero_trips(self):
n = 0
expected_output = 0
self.assertEqual(shortest_trips(n), expected_output)

def test_negative_trips(self):
n = -10
expected_output = 0
self.assertEqual(shortest_trips(n), expected_output)

def test_large_number_of_trips(self):
n = 1000000
expected_output = 500000
self.assertEqual(shortest_trips(n), expected_output)
21 changes: 21 additions & 0 deletions linked_list/206_reverse_linked_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
#TODO
"""
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next

def reverseList(head):
prev = None
next = None
cur = head
while cur != None:
next = cur.next
cur.next = prev
# update pointers
prev = cur
cur = next

return prev
47 changes: 47 additions & 0 deletions linked_list/2095_delete_the_middle_node_of_a_linked_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""
2095. Delete the Middle Node of a Linked List
Medium
You are given the head of a linked list. Delete the middle node, and return the
head of the modified linked list.
The middle node of a linked list of size n is the ⌊n / 2⌋th node from the start
using 0-based indexing, where ⌊x⌋ denotes the largest integer less than or
equal to x.
For n = 1, 2, 3, 4, and 5, the middle nodes are 0, 1, 1, 2, and 2, respectively.
"""

# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next

def deleteMiddle(head):
cur = head
n = 0
while cur != None:
cur = cur.next
n+=1

# handle the single element list
if n==1:
return None

middle = n // 2
i = 0
prev = None
cur = head
while True:
if i == middle:
prev.next = cur.next
break
prev = cur
cur = cur.next
i+=1

return head


44 changes: 44 additions & 0 deletions string_array/283_move_zeroes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
283. Move Zeroes
Easy
Given an integer array nums, move all 0's to the end of it while maintaining
the relative order of the non-zero elements.
Note that you must do this in-place without making a copy of the array.
"""

def moveZeroes(nums):

slow = 0
for fast in range(len(nums)):
val_fast = nums[fast]
val_slow = nums[slow]
if nums[fast] != 0 and nums[slow] == 0:
nums[slow], nums[fast] = nums[fast], nums[slow]

# wait while we find a non-zero element to
# swap with you
if nums[slow] != 0:
slow += 1


# cur1 = 0
# cur2 = len(nums)-1
#
# while cur1 < cur2:
# val1 = nums[cur1]
# val2 = nums[cur2]
#
# if val1==0:
# if val2 !=0:
# nums[cur1], nums[cur2] = nums[cur2], nums[cur1]
# else:
# cur2 -=1
# else:
# cur1 +=1

if __name__ == '__main__':
nums = [0,1,0,3,12]
moveZeroes(nums)
print(nums) # ->[1,3,12,0,0]
44 changes: 44 additions & 0 deletions string_array/392_is_subsequence.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

######
# DP #
######
def isSubsequence(s,t):
nxt = [{} for _ in range(len(t) + 1)]
for i in range(len(t) - 1, -1, -1):
nxt[i] = nxt[i + 1].copy()
nxt[i][t[i]] = i + 1

print("hello")

pass




################
# TWO POINTERS #
################
#def isSubsequence(s, t):
# slow = 0
# if s=="":
# return True
#
#
# for fast in range(len(t)):
# if slow==len(s):
# break
#
# if s[slow] == t[fast]:
# slow+=1
# if slow == len(s):
# return True
#
# return False




if __name__ == '__main__':
s = "abc"
t = "ahbgdc"
print(isSubsequence(s,t)) # -> True
40 changes: 40 additions & 0 deletions string_array/605_can_place_flowers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
605. Can Place Flowers
Easy
You have a long flowerbed in which some of the plots are planted, and some are
not. However, flowers cannot be planted in adjacent plots.
Given an integer array flowerbed containing 0's and 1's, where 0 means empty
and 1 means not empty, and an integer n, return true if n new flowers can be
planted in the flowerbed without violating the no-adjacent-flowers rule and
false otherwise.
"""

def canPlaceFlowers(flowerbed, n):
cur = 0
available = 0
while cur < len(flowerbed):
if flowerbed[cur] == 0:
if (cur - 1) > 0 and (cur+1)<len(flowerbed):
if flowerbed[cur-1]==0 and flowerbed[cur+1]==0:
flowerbed[cur]=1
available+=1
if cur-1<0 and cur+1<len(flowerbed):
if flowerbed[cur+1] ==0:
flowerbed[cur]=1
available+=1
if cur-1>0 and cur+1==len(flowerbed):
if flowerbed[cur-1]==0:
flowerbed[cur]=1
available+=1
cur+=1
return available==n



if __name__ == '__main__':
flowerbed = [1,0,0,0,1]
n = 1
print(canPlaceFlowers(flowerbed, n)) # -> True
Loading

0 comments on commit bbc96f2

Please sign in to comment.