Skip to content

Commit bb93f3b

Browse files
committed
Add prep combination sum
1 parent 424d7eb commit bb93f3b

File tree

2 files changed

+108
-12
lines changed

2 files changed

+108
-12
lines changed

2024/meta/prep.py

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,38 @@ def backtrack(opencount, closecount, path):
505505
backtrack(0, 0, [])
506506
return res
507507

508+
509+
############# 39. Combination Sum ############
510+
class Solution:
511+
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
512+
"""
513+
N = len(candidates), T = target, M = min(candidates)
514+
N-ary Tree height = T/M
515+
Total nodes in N-ary tree = N^(T/M+1)
516+
Time O(N^(T/M+1)) | Space O(T/M)
517+
"""
518+
candidates.sort()
519+
n = len(candidates)
520+
res = []
521+
def backtrack(i, path, total):
522+
if total == target:
523+
res.append(path.copy())
524+
return
525+
elif total > target:
526+
return
527+
528+
else:
529+
for j in range(i, n):
530+
# If candidates contains duplicates, need to skip by checking (j > 0 and candidates[j] == candidates[j-1])
531+
path.append(candidates[j])
532+
backtrack(j, path, total+candidates[j])
533+
path.pop()
534+
535+
backtrack(0, [], 0)
536+
print(res)
537+
return res
538+
539+
508540
############# 21. Merge Two Sorted Lists ############
509541
# Definition for singly-linked list.
510542
class ListNode:
@@ -589,26 +621,23 @@ def minWindow(self, s: str, t: str) -> str:
589621
m, n = len(s), len(t)
590622
if n > m:
591623
return ""
592-
cs, ct = Counter(), Counter(t)
624+
window, need = Counter(), Counter(t)
593625
res = ""
594-
i, j = 0, 0 # left, right pointer to s
595626

596-
def valid(window, need):
627+
def isValid(window, need):
597628
for c in need.keys():
598629
if window[c] < need[c]:
599630
return False
600631
return True
601632

602-
while j < m:
603-
cs[s[j]] += 1
604-
j += 1
605-
606-
while i < j and valid(cs, ct):
607-
if j-i < len(res) or res == "":
608-
res = s[i:j]
609-
cs[s[i]] -= 1
633+
i = 0
634+
for j, c in enumerate(s):
635+
window[c] += 1
636+
while i <= j and isValid(window, need):
637+
if j-i+1 < len(res) or res == "":
638+
res = s[i:j+1]
639+
window[s[i]] -= 1
610640
i += 1
611-
612641
return res
613642

614643
############# 71. Simplify Path ############
@@ -673,6 +702,21 @@ def findMaxLength(self, nums: List[int]) -> int:
673702
res = max(res, j-seen[parity])
674703
return res
675704

705+
706+
############# 56. Merge Intervals ############
707+
class Solution:
708+
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
709+
intervals.sort() # do normal sort of based on start value so mergeable intervals are next to each other
710+
711+
output = [intervals[0]]
712+
713+
for start, end in intervals:
714+
if start <= output[-1][1]:
715+
output[-1][1] = max(output[-1][1], end)
716+
else:
717+
output.append([start, end])
718+
return output
719+
676720
############# 426. Convert Binary Search Tree to Sorted Doubly Linked List #############
677721
class Solution:
678722
def treeToDoublyList(self, root: 'Optional[Node]') -> 'Optional[Node]':

backtracking/permutation-combination-subset/39. Combination Sum.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from typing import List
12
class Solution:
23
def combinationSum(self, nums: List[int], target: int) -> List[List[int]]:
34
res = []
@@ -18,3 +19,54 @@ def dfs(i, path, total):
1819

1920
dfs(0, [], 0)
2021
return res
22+
23+
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
24+
candidates.sort()
25+
n = len(candidates)
26+
res = []
27+
def backtrack(i, path, total):
28+
if total == target:
29+
res.append(path.copy())
30+
return
31+
elif total > target or i >= n:
32+
return
33+
34+
else:
35+
for j in range(i, n):
36+
path.append(candidates[j])
37+
backtrack(j, path, total+candidates[j])
38+
path.pop()
39+
40+
backtrack(0, [], 0)
41+
return res
42+
43+
def combination_sum_neg(candidates, target):
44+
candidates.sort()
45+
n = len(candidates)
46+
def backtrack(start, target, path):
47+
if target == 0:
48+
result.append(path[:])
49+
return
50+
51+
for i in range(start, n):
52+
if i > start and candidates[i] == candidates[i-1]:
53+
continue
54+
55+
if candidates[i] > 0 and candidates[i] > target:
56+
break
57+
58+
if candidates[i] < 0 and candidates[i] < target:
59+
continue
60+
61+
path.append(candidates[i])
62+
backtrack(i, target - candidates[i], path)
63+
path.pop()
64+
65+
result = []
66+
backtrack(0, target, [])
67+
return result
68+
69+
# Example usage
70+
candidates = [2, -3, 7, 5, -2]
71+
target = 5
72+
print(combination_sum_neg(candidates, target))

0 commit comments

Comments
 (0)