Skip to content

Commit 0c6afd4

Browse files
committed
2 parents 7a7b7f9 + 1592f48 commit 0c6afd4

File tree

8 files changed

+378
-2
lines changed

8 files changed

+378
-2
lines changed

pythonProblems/dp/boxes.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
from typing import List
3+
4+
5+
class Box:
6+
def __init__(self, width, height, depth):
7+
self.width = width
8+
self.height = height
9+
self.depth = depth
10+
11+
12+
def boxes(stack: List[Box]) -> int:
13+
n = len(stack)
14+
boxes: List[Box] = []
15+
for eachbox in stack:
16+
boxes.append(eachbox) ## the box
17+
boxes.append(Box(min(eachbox.height, eachbox.depth), eachbox.width, max(eachbox.height, eachbox.depth))) ## the box rotated, with width as height, width as min(height, depth) and depth as min(height, depth)
18+
boxes.append(Box(min(eachbox.height, eachbox.width), eachbox.depth, max(eachbox.height, eachbox.width))) ## the box rotated, with depth as height, width as min(height, width), and depth as min(height, width)
19+
n *= 3
20+
21+
boxes.sort(key=lambda b: b.depth * b.width, reverse=True)
22+
23+
msh = [0] * n
24+
25+
for i in range(len(msh)):
26+
msh[i] = boxes[i].height
27+
28+
for i in range(1, n):
29+
for j in range(0, i):
30+
if boxes[i].width < boxes[j].width and boxes[i].depth < boxes[j].depth: ## if the current target box's width is less then the subproblem box width, and depth likewise
31+
if msh[i] < msh[j] + boxes[i].height: ## we can make a taller combination if the current dp target solution is less then the smaller dp solution + the target box height
32+
msh[i] = msh[j] + boxes[i].height ## we assign the target problem the result of subproblem j's solution + the target box's height
33+
34+
return max(msh) ## return the max height, which is the last element in the dp table
35+
36+
37+
if __name__ == '__main__':
38+
arr = [Box(6, 4, 7), Box(2, 1, 3), Box(5, 4, 6), Box(12, 10, 32)]
39+
print(boxes(arr))
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from typing import List
2+
3+
4+
class Solution:
5+
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
6+
sorted_candidates = sorted(candidates)
7+
combos = self.find_combos(sorted_candidates, target)
8+
filtered_combos = []
9+
for eachcombo in combos:
10+
if sorted(eachcombo) in filtered_combos:
11+
continue
12+
else:
13+
filtered_combos.append(sorted(eachcombo))
14+
print(filtered_combos)
15+
return filtered_combos
16+
17+
def find_combos(self, nums: List[int], target: int, curr_total_arr: List[int] = None, combos: List[List[int]] = None) -> List[List[int]]:
18+
curr_total = 0
19+
if curr_total_arr is None:
20+
curr_total_arr = []
21+
else:
22+
curr_total = sum(curr_total_arr)
23+
if combos is None:
24+
combos = []
25+
for eachnum in nums:
26+
if eachnum + curr_total < target:
27+
acquired_combos = self.find_combos(nums, target, curr_total_arr + [eachnum], combos)
28+
for eachcombo in acquired_combos:
29+
if eachcombo not in combos:
30+
combos.append(eachcombo)
31+
elif eachnum + curr_total > target:
32+
return [] + combos
33+
else:
34+
if sorted(curr_total_arr + [eachnum]) not in combos and curr_total + eachnum == target:
35+
return combos + sorted([curr_total_arr + [eachnum]])
36+
return []
37+
return combos
38+
39+
if __name__ == '__main__':
40+
candidates = [36,21,2,3,23,24,38,22,11,14,15,25,32,19,35,26,31,13,34,29,12,37,17,20,39,30,40,28,27,33]
41+
target = 35
42+
sol = Solution()
43+
sol.combinationSum(candidates, target)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from typing import List
2+
3+
4+
class Solution:
5+
def combinationSum2(self, candidates: List[int], target: int, combos: List[List[int]] = None, curr_combo_sum: int = None, curr_combo: List[int] = None, curr_combo_indices: List[int] = None) -> List[List[int]]:
6+
if sum(candidates) < target:
7+
return []
8+
if combos is None:
9+
combos = []
10+
if curr_combo is None:
11+
curr_combo = []
12+
if curr_combo_indices is None:
13+
curr_combo_indices = []
14+
15+
curr_combo_sum = 0
16+
if not combos is None:
17+
curr_combo_sum = sum(curr_combo)
18+
19+
for ind, elem in enumerate(candidates):
20+
if elem + curr_combo_sum > target:
21+
continue
22+
if elem + curr_combo_sum == target and ind not in curr_combo_indices:
23+
combo_sorted = sorted(curr_combo + [elem])
24+
if combo_sorted not in combos:
25+
combos.append(combo_sorted)
26+
elif ind not in curr_combo_indices:
27+
acquired_combos = self.combinationSum2(candidates, target, combos, curr_combo_sum, curr_combo + [elem], curr_combo_indices + [ind])
28+
for eachcombo in acquired_combos:
29+
eachcombo_sorted = sorted(eachcombo)
30+
if eachcombo_sorted not in combos:
31+
combos.append(eachcombo_sorted)
32+
return combos
33+
34+
if __name__ == '__main__':
35+
sol = Solution()
36+
candidates = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
37+
target = 30
38+
print(sol.combinationSum2(candidates, target))
39+

pythonProblems/dp/countAndSay.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
class Solution:
3+
4+
def gen_number(self, num: str) -> str:
5+
sequence_count = {}
6+
curr_key = ''
7+
generated_string = ''
8+
for eachdigit in num:
9+
if eachdigit in sequence_count:
10+
sequence_count[eachdigit] += 1
11+
elif len(sequence_count) == 0: ## initial case, when dict is empty
12+
sequence_count[eachdigit] = 1
13+
curr_key = eachdigit
14+
else:
15+
generated_string += str(sequence_count[curr_key]) + curr_key
16+
curr_key = eachdigit
17+
sequence_count.clear()
18+
sequence_count[eachdigit] = 1
19+
if len(sequence_count) > 0:
20+
generated_string += str(sequence_count[curr_key]) + curr_key
21+
return generated_string
22+
23+
def countAndSay(self, n: int) -> str:
24+
if n == 1:
25+
return '1'
26+
else:
27+
sequence_elements = ['1']
28+
i = 0
29+
while len(sequence_elements) < n:
30+
sequence_elements.append(self.gen_number(sequence_elements[i]))
31+
i += 1
32+
print(sequence_elements)
33+
return sequence_elements[n - 1]
34+
35+
if __name__ == '__main__':
36+
sol = Solution()
37+
target = 5
38+
sol.countAndSay(target)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import random
2+
from typing import List
3+
4+
5+
class Solution:
6+
def firstMissingPositive(self, nums: List[int]) -> int:
7+
min_number = -1
8+
max_number = 0
9+
gap_base = -1
10+
for eachnum in nums:
11+
if eachnum > 0:
12+
if min_number == -1:
13+
## initialize all trackers
14+
max_number = eachnum
15+
min_number = eachnum
16+
else:
17+
gap = abs(eachnum - max_number)
18+
gap_base_diff = abs(eachnum - gap_base)
19+
if gap > 1 and ((eachnum > max_number and gap_base == -1) or (eachnum < max_number and gap_base == -1) or (eachnum < max_number and gap_base_diff == 1) or (eachnum < max_number and gap_base_diff > 0 and eachnum < gap_base)): ## before and after
20+
if gap_base_diff == 1:
21+
gap_base = eachnum
22+
elif gap_base == -1:
23+
gap_base = min(max_number, eachnum)
24+
else:
25+
gap_base = min(max_number, eachnum)
26+
min_number = min(min_number, eachnum)
27+
max_number = max(max_number, eachnum)
28+
if min_number != 0 and min_number > 1:
29+
return 1
30+
if gap_base == -1:
31+
## no gaps detected, check max, if max is 0, return 1
32+
if max_number == 0:
33+
return 1
34+
# return max + 1
35+
return max_number + 1
36+
else:
37+
return gap_base + 1
38+
39+
40+
41+
if __name__ == '__main__':
42+
sol = Solution()
43+
arrs = [
44+
[1,2,0],
45+
[3,4,-1,1],
46+
[7,8,9,11,12],
47+
[1, 2, 3, 50, 48, 5214, 32, 6324, 234, -32, -1231, -432134, -5123, -412243, -44, -324, 0],
48+
[1, 2, 3, 6, 7, 4],
49+
[40, 33, 50, -11, 0, 12, 50, 1, 33, -1, -3, 27, 29, -19],
50+
[1,2,6,3,5,4]
51+
]
52+
# for i in range(5):
53+
# new_arr = []
54+
# for j in range(random.randint(10, 30)):
55+
# new_arr.append(random.randint(-20, 50))
56+
# arrs.append(new_arr)
57+
# new_arr = []
58+
for eacharr in arrs:
59+
print('testing {}'.format(eacharr))
60+
print(sol.firstMissingPositive(eacharr))

pythonProblems/dp/lcs.py

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,83 @@
1-
def lcs(sub1: str, sub2: str) -> str:
2-
pass
1+
from pprint import pprint
2+
from typing import List
3+
4+
5+
def find_subsequence_len(str1: str, str2: str, max_length=0) -> int:
6+
for ind, elem in enumerate(str1):
7+
if elem in str2:
8+
max_length = max(
9+
max_length, 1 + find_subsequence_len(str1[ind + 1:], str2[str2.index(elem) + 1:]))
10+
return max_length
11+
12+
13+
def lcs(substr1: str, substr2: str) -> int:
14+
while len(substr1) > 0 and len(substr2) > 0:
15+
if substr1[-1] != substr2[-1]:
16+
return max(lcs(substr1[:-1], substr2), lcs(substr1, substr2[:-1]))
17+
return 1 + lcs(substr1[:-1], substr2[:-1])
18+
return 0
19+
20+
21+
def print_lcs(substr1: str, substr2: str) -> str:
22+
table = []
23+
# initialize table
24+
for _ in substr1 + " ":
25+
table_row = []
26+
for __ in substr2 + " ":
27+
table_row.append(0)
28+
table.append(table_row)
29+
table_row = []
30+
31+
for i in range(1, len(substr1) + 1):
32+
for j in range(1, len(substr2) + 1):
33+
if substr2[j - 1] == substr1[i - 1]: # if both characters match
34+
# characters match, set the diagonal cell to the curr value + 1
35+
table[i][j] = table[i - 1][j - 1] + 1
36+
else:
37+
# either up or left in the lookup table
38+
table[i][j] = max(table[i - 1][j], table[i][j - 1])
39+
# start at bottom right, and follow the path, taking a diagonal left with the letters are the same
40+
41+
startCol = len(table[len(table) - 1]) - 1
42+
startRow = len(table) - 1
43+
44+
_substr1 = " " + substr1
45+
_substr2 = " " + substr2
46+
substr = ''
47+
pprint(table)
48+
while startCol != 0 and startRow != 0:
49+
if _substr1[startRow] == _substr2[startCol]:
50+
# jump diagonal, add letter
51+
substr += _substr1[startRow]
52+
startRow -= 1
53+
startCol -= 1
54+
else:
55+
# evaluate left
56+
left_ = -1
57+
if startCol > 0:
58+
left_ = table[startRow][startCol - 1]
59+
# evaluate top
60+
top_ = -1
61+
if startRow > 0:
62+
top_ = table[startRow - 1][startCol]
63+
64+
if left_ == top_:
65+
startCol -= 1
66+
if left_ != -1 and top_ != -1:
67+
startRow -= 1 if top_ > left_ else 0
68+
startCol -= 1 if left_ > top_ else 0
69+
if left_ == -1:
70+
# move up
71+
startRow -= 1
72+
if top_ == -1:
73+
startCol -= 1
74+
return substr[::-1]
75+
76+
77+
if __name__ == '__main__':
78+
x = 'abcbdab'
79+
y = 'bdcaba'
80+
print(lcs(x, y))
81+
x2 = 'xmjyauzadfsf'
82+
y2 = 'mzjawxuwqrwe'
83+
print(print_lcs(x2, y2))
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from pprint import pprint
2+
3+
def longestSubstring(substr1: str, substr2: str) -> str:
4+
table = []
5+
for _ in substr1:
6+
table_row = []
7+
for __ in substr2:
8+
table_row.append(0)
9+
table.append(table_row)
10+
table_row = []
11+
12+
for i in range(len(substr1)):
13+
for j in range(len(substr2)):
14+
if substr1[i] == substr2[j]:
15+
if i == 0:
16+
table[i][j] = 1
17+
elif j == 0:
18+
table[i][j] = 1
19+
else:
20+
table[i][j] = table[i - 1][j - 1] + 1
21+
22+
coords = []
23+
max_value = 0
24+
for eachrow in table:
25+
max_value = max(max_value, max(eachrow))
26+
27+
for i in range(len(table)):
28+
for j in range(len(table[i])):
29+
if table[i][j] == max_value:
30+
coords.append((i, j))
31+
32+
substrs = []
33+
for eachcoord in coords:
34+
x_ = eachcoord[1]
35+
y_ = eachcoord[0]
36+
substr = ''
37+
while table[y_][x_] != 0 and x_ >= 0 and y_ >= 0:
38+
substr += substr1[x_]
39+
x_ -= 1
40+
y_ -= 1
41+
substrs.append(substr)
42+
print(substrs)
43+
44+
45+
46+
47+
if __name__ == '__main__':
48+
s1 = 'abab'
49+
s2 = 'baba'
50+
longestSubstring(s1, s2)

pythonProblems/dp/searchInsert.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from typing import List
2+
3+
4+
class Solution:
5+
def searchInsert(self, nums: List[int], target: int) -> int:
6+
mid = len(nums) // 2
7+
l = 0
8+
r = len(nums) - 1
9+
while l < r:
10+
if nums[mid] > target:
11+
r = mid - 1
12+
elif nums[mid] < target:
13+
l = mid + 1
14+
elif nums[mid] == target:
15+
return mid
16+
mid = l + ((r - l) // 2)
17+
if l == -1 or r == -1:
18+
return 0
19+
return mid + 1 if nums[mid] < target else mid
20+
21+
22+
if __name__ == '__main__':
23+
sol = Solution()
24+
nums = [1, 3, 5, 6]
25+
target = 0
26+
print(sol.searchInsert(nums, target))

0 commit comments

Comments
 (0)