Compare commits

...

13 Commits

Author SHA1 Message Date
Deven 88b99caf11 Time: 38 ms (85.56%), Space: 18.1 MB (81.8%) - LeetHub 2025-12-10 16:30:29 -05:00
Deven 2c96c57870 Create README - LeetHub 2025-12-10 16:30:28 -05:00
Deven 6bc1bcb772 Time: 4 ms (13.43%), Space: 18.5 MB (85.36%) - LeetHub 2025-12-08 18:17:52 -05:00
Deven f174c1edea Create README - LeetHub 2025-12-08 18:17:51 -05:00
Deven 3c88ab7152 Time: 67 ms (60.36%), Space: 23.4 MB (9.25%) - LeetHub 2025-12-04 17:28:52 -05:00
Deven cbef5fb714 Create README - LeetHub 2025-12-04 17:28:52 -05:00
Deven c45b01a838 Time: 814 ms (5.02%), Space: 57 MB (17.32%) - LeetHub 2025-12-01 11:54:18 -05:00
Deven cc492aa3b2 Create README - LeetHub 2025-12-01 11:54:17 -05:00
Deven cf8b99d511 Time: 43 ms (93.63%), Space: 18.2 MB (59.46%) - LeetHub 2025-11-30 22:34:41 -05:00
Deven c90ee7f934 Time: 43 ms (93.63%), Space: 18.2 MB (59.46%) - LeetHub 2025-11-30 22:34:13 -05:00
Deven 10ff3a0da5 Create README - LeetHub 2025-11-30 22:34:12 -05:00
Deven 29c783e08b Time: 810 ms (40.98%), Space: 18.7 MB (34.3%) - LeetHub 2025-11-30 20:48:35 -05:00
Deven 79b324dd16 Create README - LeetHub 2025-11-30 20:48:34 -05:00
12 changed files with 525 additions and 0 deletions
@@ -0,0 +1,68 @@
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
if k == 1:
return head
dummyHead = ListNode(-1, head)
beforeSeg = dummyHead
firstInSeg = head
lastInSeg = None
afterSeg = None
# Get initial values for lastInSeg and afterSeg
curr = head
for i in range(k):
if i == k - 1:
lastInSeg = curr
afterSeg = curr.next
elif curr is None:
return head
curr = curr.next
# hold one before segment
# hold last in segment
# hold one after segment
while lastInSeg is not None:
# in segment, flip all links
prev = None
curr = beforeSeg.next
next = beforeSeg.next.next
for i in range(k):
newPrev = curr
newCurr = next
newNext = next.next if next is not None else None
curr.next = prev
prev, curr, next = newPrev, newCurr, newNext
beforeSeg.next = lastInSeg
firstInSeg.next = afterSeg
beforeSeg = firstInSeg
firstInSeg = afterSeg
curr = firstInSeg
lastInSeg = None
afterSeg = None
for i in range(k):
if curr is None:
break
elif i == k - 1:
lastInSeg = curr
afterSeg = curr.next
curr = curr.next
return dummyHead.next
+32
View File
@@ -0,0 +1,32 @@
<h2><a href="https://leetcode.com/problems/reverse-nodes-in-k-group">25. Reverse Nodes in k-Group</a></h2><h3>Hard</h3><hr><p>Given the <code>head</code> of a linked list, reverse the nodes of the list <code>k</code> at a time, and return <em>the modified list</em>.</p>
<p><code>k</code> is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of <code>k</code> then left-out nodes, in the end, should remain as it is.</p>
<p>You may not alter the values in the list&#39;s nodes, only nodes themselves may be changed.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/10/03/reverse_ex1.jpg" style="width: 542px; height: 222px;" />
<pre>
<strong>Input:</strong> head = [1,2,3,4,5], k = 2
<strong>Output:</strong> [2,1,4,3,5]
</pre>
<p><strong class="example">Example 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/10/03/reverse_ex2.jpg" style="width: 542px; height: 222px;" />
<pre>
<strong>Input:</strong> head = [1,2,3,4,5], k = 3
<strong>Output:</strong> [3,2,1,4,5]
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li>The number of nodes in the list is <code>n</code>.</li>
<li><code>1 &lt;= k &lt;= n &lt;= 5000</code></li>
<li><code>0 &lt;= Node.val &lt;= 1000</code></li>
</ul>
<p>&nbsp;</p>
<p><strong>Follow-up:</strong> Can you solve the problem in <code>O(1)</code> extra memory space?</p>
+31
View File
@@ -0,0 +1,31 @@
"""
# Definition for a Node.
class Node:
def __init__(self, val = 0, neighbors = None):
self.val = val
self.neighbors = neighbors if neighbors is not None else []
"""
from typing import Optional
from collections import deque
class Solution:
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
if not node:
return node
newHead = Node(node.val)
frontier = deque([ node ])
nodeMapping = { node.val: newHead }
while len(frontier) > 0:
current = frontier.popleft()
for n in current.neighbors:
if n.val not in nodeMapping:
newNode = Node(n.val)
nodeMapping[newNode.val] = newNode
frontier.append(n)
nodeMapping[current.val].neighbors.append(nodeMapping[n.val])
return newHead
+62
View File
@@ -0,0 +1,62 @@
<h2><a href="https://leetcode.com/problems/clone-graph">133. Clone Graph</a></h2><h3>Medium</h3><hr><p>Given a reference of a node in a <strong><a href="https://en.wikipedia.org/wiki/Connectivity_(graph_theory)#Connected_graph" target="_blank">connected</a></strong> undirected graph.</p>
<p>Return a <a href="https://en.wikipedia.org/wiki/Object_copying#Deep_copy" target="_blank"><strong>deep copy</strong></a> (clone) of the graph.</p>
<p>Each node in the graph contains a value (<code>int</code>) and a list (<code>List[Node]</code>) of its neighbors.</p>
<pre>
class Node {
public int val;
public List&lt;Node&gt; neighbors;
}
</pre>
<p>&nbsp;</p>
<p><strong>Test case format:</strong></p>
<p>For simplicity, each node&#39;s value is the same as the node&#39;s index (1-indexed). For example, the first node with <code>val == 1</code>, the second node with <code>val == 2</code>, and so on. The graph is represented in the test case using an adjacency list.</p>
<p><b>An adjacency list</b> is a collection of unordered <b>lists</b> used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.</p>
<p>The given node will always be the first node with <code>val = 1</code>. You must return the <strong>copy of the given node</strong> as a reference to the cloned graph.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2019/11/04/133_clone_graph_question.png" style="width: 454px; height: 500px;" />
<pre>
<strong>Input:</strong> adjList = [[2,4],[1,3],[2,4],[1,3]]
<strong>Output:</strong> [[2,4],[1,3],[2,4],[1,3]]
<strong>Explanation:</strong> There are 4 nodes in the graph.
1st node (val = 1)&#39;s neighbors are 2nd node (val = 2) and 4th node (val = 4).
2nd node (val = 2)&#39;s neighbors are 1st node (val = 1) and 3rd node (val = 3).
3rd node (val = 3)&#39;s neighbors are 2nd node (val = 2) and 4th node (val = 4).
4th node (val = 4)&#39;s neighbors are 1st node (val = 1) and 3rd node (val = 3).
</pre>
<p><strong class="example">Example 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/01/07/graph.png" style="width: 163px; height: 148px;" />
<pre>
<strong>Input:</strong> adjList = [[]]
<strong>Output:</strong> [[]]
<strong>Explanation:</strong> Note that the input contains one empty list. The graph consists of only one node with val = 1 and it does not have any neighbors.
</pre>
<p><strong class="example">Example 3:</strong></p>
<pre>
<strong>Input:</strong> adjList = []
<strong>Output:</strong> []
<strong>Explanation:</strong> This an empty graph, it does not have any nodes.
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li>The number of nodes in the graph is in the range <code>[0, 100]</code>.</li>
<li><code>1 &lt;= Node.val &lt;= 100</code></li>
<li><code>Node.val</code> is unique for each node.</li>
<li>There are no repeated edges and no self-loops in the graph.</li>
<li>The Graph is connected and all nodes can be visited starting from the given node.</li>
</ul>
@@ -0,0 +1,60 @@
class Solution:
def calculate(self, s: str) -> int:
"""
Complexities:
Time: O(n)
Space: O(n)
where n = len(s)
"""
numbers = "0123456789"
# Read from left to right: save in stack (full number or operator)
# - save number
# - on operator:
# -- if * or /, evaluate
# -- if + or -, wait and continue
currentNumber = 0
stack = []
# Evaluate numbers and create stack (of additions + subtractions)
for c in s + "\0":
if c == " ":
continue
elif c in numbers:
digit = int(c)
currentNumber = (currentNumber * 10) + digit
else:
stack.append(currentNumber)
currentNumber = 0
if len(stack) >= 3 and stack[-2] in "*/":
rOperand = stack.pop()
operator = stack.pop()
lOperand = stack.pop()
if operator == "*":
stack.append(lOperand * rOperand)
elif operator == "/":
stack.append(int(lOperand / rOperand))
stack.append(c)
# Pop off null terminator
stack.pop()
# Evaluate all additions and subtractions from stack
current = stack[0]
for i in range(1, len(stack) - 1, 2):
operator = stack[i]
rOperand = stack[i + 1]
if operator == "+":
current += rOperand
elif operator == "-":
current -= rOperand
return current
+29
View File
@@ -0,0 +1,29 @@
<h2><a href="https://leetcode.com/problems/basic-calculator-ii">227. Basic Calculator II</a></h2><h3>Medium</h3><hr><p>Given a string <code>s</code> which represents an expression, <em>evaluate this expression and return its value</em>.&nbsp;</p>
<p>The integer division should truncate toward zero.</p>
<p>You may assume that the given expression is always valid. All intermediate results will be in the range of <code>[-2<sup>31</sup>, 2<sup>31</sup> - 1]</code>.</p>
<p><strong>Note:</strong> You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as <code>eval()</code>.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre><strong>Input:</strong> s = "3+2*2"
<strong>Output:</strong> 7
</pre><p><strong class="example">Example 2:</strong></p>
<pre><strong>Input:</strong> s = " 3/2 "
<strong>Output:</strong> 1
</pre><p><strong class="example">Example 3:</strong></p>
<pre><strong>Input:</strong> s = " 3+5 / 2 "
<strong>Output:</strong> 5
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= s.length &lt;= 3 * 10<sup>5</sup></code></li>
<li><code>s</code> consists of integers and operators <code>(&#39;+&#39;, &#39;-&#39;, &#39;*&#39;, &#39;/&#39;)</code> separated by some number of spaces.</li>
<li><code>s</code> represents <strong>a valid expression</strong>.</li>
<li>All the integers in the expression are non-negative integers in the range <code>[0, 2<sup>31</sup> - 1]</code>.</li>
<li>The answer is <strong>guaranteed</strong> to fit in a <strong>32-bit integer</strong>.</li>
</ul>
+24
View File
@@ -0,0 +1,24 @@
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
"""
Complexities:
Time: O(mn)
Space: O(m)
where n = len(coins), m = amount
"""
dp = [-1] * (amount + 1)
dp[0] = 0
for i in range(amount + 1):
for coinValue in coins:
if dp[i] == -1 or i + coinValue > amount:
continue
elif dp[i + coinValue] == -1:
dp[i + coinValue] = dp[i] + 1
else:
dp[i + coinValue] = min(dp[i + coinValue], dp[i] + 1)
print(dp)
return dp[amount]
+37
View File
@@ -0,0 +1,37 @@
<h2><a href="https://leetcode.com/problems/coin-change">322. Coin Change</a></h2><h3>Medium</h3><hr><p>You are given an integer array <code>coins</code> representing coins of different denominations and an integer <code>amount</code> representing a total amount of money.</p>
<p>Return <em>the fewest number of coins that you need to make up that amount</em>. If that amount of money cannot be made up by any combination of the coins, return <code>-1</code>.</p>
<p>You may assume that you have an infinite number of each kind of coin.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre>
<strong>Input:</strong> coins = [1,2,5], amount = 11
<strong>Output:</strong> 3
<strong>Explanation:</strong> 11 = 5 + 5 + 1
</pre>
<p><strong class="example">Example 2:</strong></p>
<pre>
<strong>Input:</strong> coins = [2], amount = 3
<strong>Output:</strong> -1
</pre>
<p><strong class="example">Example 3:</strong></p>
<pre>
<strong>Input:</strong> coins = [1], amount = 0
<strong>Output:</strong> 0
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= coins.length &lt;= 12</code></li>
<li><code>1 &lt;= coins[i] &lt;= 2<sup>31</sup> - 1</code></li>
<li><code>0 &lt;= amount &lt;= 10<sup>4</sup></code></li>
</ul>
@@ -0,0 +1,56 @@
class Solution:
def minimumTime(self, n: int, relations: List[List[int]], time: List[int]) -> int:
"""
Complexities:
Time: O(n^2)
Space: O(r)
where n = n, r = len(relations)
"""
# courses been taken array
# - O(r) time / O(r) space
hasPrereq = [False] * n
prereqMap = [set() for i in range(n)]
leadsToMap = [set() for i in range(n)]
for prevCourse, nextCourse in relations:
hasPrereq[nextCourse - 1] = True
prereqMap[nextCourse - 1].add(prevCourse)
leadsToMap[prevCourse - 1].add(nextCourse)
# O(n) space
timeUntilComplete = [-1] * n
coursesCalculated = 0
maxOverallTimeFound = 0
toResolve = set()
# calculate timeUntilComplete for no prereq courses
# - O(n) time
for i in range(n):
if not hasPrereq[i]:
timeUntilComplete[i] = time[i]
maxOverallTimeFound = max(maxOverallTimeFound, time[i])
coursesCalculated += 1
toResolve.update(leadsToMap[i])
# find all timeUntilComplete
# - if all prereq times are known, then calc
# - O(n^2) time
while len(toResolve) > 0:
nextCourse = toResolve.pop()
maxPrereqTime = -1
for prereq in prereqMap[nextCourse - 1]:
if timeUntilComplete[prereq - 1] == -1:
maxPrereqTime = -1
break
maxPrereqTime = max(maxPrereqTime, timeUntilComplete[prereq - 1])
if maxPrereqTime > -1:
timeUntilComplete[nextCourse - 1] = maxPrereqTime + time[nextCourse - 1]
maxOverallTimeFound = max(maxOverallTimeFound, timeUntilComplete[nextCourse - 1])
coursesCalculated += 1
toResolve.update(leadsToMap[nextCourse - 1])
return maxOverallTimeFound
+54
View File
@@ -0,0 +1,54 @@
<h2><a href="https://leetcode.com/problems/parallel-courses-iii">2050. Parallel Courses III</a></h2><h3>Hard</h3><hr><p>You are given an integer <code>n</code>, which indicates that there are <code>n</code> courses labeled from <code>1</code> to <code>n</code>. You are also given a 2D integer array <code>relations</code> where <code>relations[j] = [prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code> denotes that course <code>prevCourse<sub>j</sub></code> has to be completed <strong>before</strong> course <code>nextCourse<sub>j</sub></code> (prerequisite relationship). Furthermore, you are given a <strong>0-indexed</strong> integer array <code>time</code> where <code>time[i]</code> denotes how many <strong>months</strong> it takes to complete the <code>(i+1)<sup>th</sup></code> course.</p>
<p>You must find the <strong>minimum</strong> number of months needed to complete all the courses following these rules:</p>
<ul>
<li>You may start taking a course at <strong>any time</strong> if the prerequisites are met.</li>
<li><strong>Any number of courses</strong> can be taken at the <strong>same time</strong>.</li>
</ul>
<p>Return <em>the <strong>minimum</strong> number of months needed to complete all the courses</em>.</p>
<p><strong>Note:</strong> The test cases are generated such that it is possible to complete every course (i.e., the graph is a directed acyclic graph).</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<strong><img alt="" src="https://assets.leetcode.com/uploads/2021/10/07/ex1.png" style="width: 392px; height: 232px;" /></strong>
<pre>
<strong>Input:</strong> n = 3, relations = [[1,3],[2,3]], time = [3,2,5]
<strong>Output:</strong> 8
<strong>Explanation:</strong> The figure above represents the given graph and the time required to complete each course.
We start course 1 and course 2 simultaneously at month 0.
Course 1 takes 3 months and course 2 takes 2 months to complete respectively.
Thus, the earliest time we can start course 3 is at month 3, and the total time required is 3 + 5 = 8 months.
</pre>
<p><strong class="example">Example 2:</strong></p>
<strong><img alt="" src="https://assets.leetcode.com/uploads/2021/10/07/ex2.png" style="width: 500px; height: 365px;" /></strong>
<pre>
<strong>Input:</strong> n = 5, relations = [[1,5],[2,5],[3,5],[3,4],[4,5]], time = [1,2,3,4,5]
<strong>Output:</strong> 12
<strong>Explanation:</strong> The figure above represents the given graph and the time required to complete each course.
You can start courses 1, 2, and 3 at month 0.
You can complete them after 1, 2, and 3 months respectively.
Course 4 can be taken only after course 3 is completed, i.e., after 3 months. It is completed after 3 + 4 = 7 months.
Course 5 can be taken only after courses 1, 2, 3, and 4 have been completed, i.e., after max(1,2,3,7) = 7 months.
Thus, the minimum time needed to complete all the courses is 7 + 5 = 12 months.
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= n &lt;= 5 * 10<sup>4</sup></code></li>
<li><code>0 &lt;= relations.length &lt;= min(n * (n - 1) / 2, 5 * 10<sup>4</sup>)</code></li>
<li><code>relations[j].length == 2</code></li>
<li><code>1 &lt;= prevCourse<sub>j</sub>, nextCourse<sub>j</sub> &lt;= n</code></li>
<li><code>prevCourse<sub>j</sub> != nextCourse<sub>j</sub></code></li>
<li>All the pairs <code>[prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code> are <strong>unique</strong>.</li>
<li><code>time.length == n</code></li>
<li><code>1 &lt;= time[i] &lt;= 10<sup>4</sup></code></li>
<li>The given graph is a directed acyclic graph.</li>
</ul>
@@ -0,0 +1,17 @@
class Solution:
def bestClosingTime(self, customers: str) -> int:
penalty = 0
minPenalty = 0
bestHour = 0
for hour, hasCustomers in enumerate(customers):
if hasCustomers == "Y":
penalty -= 1
else:
penalty += 1
if penalty < minPenalty:
minPenalty = penalty
bestHour = hour + 1
return bestHour
+55
View File
@@ -0,0 +1,55 @@
<h2><a href="https://leetcode.com/problems/minimum-penalty-for-a-shop">2483. Minimum Penalty for a Shop</a></h2><h3>Medium</h3><hr><p>You are given the customer visit log of a shop represented by a <strong>0-indexed</strong> string <code>customers</code> consisting only of characters <code>&#39;N&#39;</code> and <code>&#39;Y&#39;</code>:</p>
<ul>
<li>if the <code>i<sup>th</sup></code> character is <code>&#39;Y&#39;</code>, it means that customers come at the <code>i<sup>th</sup></code> hour</li>
<li>whereas <code>&#39;N&#39;</code> indicates that no customers come at the <code>i<sup>th</sup></code> hour.</li>
</ul>
<p>If the shop closes at the <code>j<sup>th</sup></code> hour (<code>0 &lt;= j &lt;= n</code>), the <strong>penalty</strong> is calculated as follows:</p>
<ul>
<li>For every hour when the shop is open and no customers come, the penalty increases by <code>1</code>.</li>
<li>For every hour when the shop is closed and customers come, the penalty increases by <code>1</code>.</li>
</ul>
<p>Return<em> the <strong>earliest</strong> hour at which the shop must be closed to incur a <strong>minimum</strong> penalty.</em></p>
<p><strong>Note</strong> that if a shop closes at the <code>j<sup>th</sup></code> hour, it means the shop is closed at the hour <code>j</code>.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre>
<strong>Input:</strong> customers = &quot;YYNY&quot;
<strong>Output:</strong> 2
<strong>Explanation:</strong>
- Closing the shop at the 0<sup>th</sup> hour incurs in 1+1+0+1 = 3 penalty.
- Closing the shop at the 1<sup>st</sup> hour incurs in 0+1+0+1 = 2 penalty.
- Closing the shop at the 2<sup>nd</sup> hour incurs in 0+0+0+1 = 1 penalty.
- Closing the shop at the 3<sup>rd</sup> hour incurs in 0+0+1+1 = 2 penalty.
- Closing the shop at the 4<sup>th</sup> hour incurs in 0+0+1+0 = 1 penalty.
Closing the shop at 2<sup>nd</sup> or 4<sup>th</sup> hour gives a minimum penalty. Since 2 is earlier, the optimal closing time is 2.
</pre>
<p><strong class="example">Example 2:</strong></p>
<pre>
<strong>Input:</strong> customers = &quot;NNNNN&quot;
<strong>Output:</strong> 0
<strong>Explanation:</strong> It is best to close the shop at the 0<sup>th</sup> hour as no customers arrive.</pre>
<p><strong class="example">Example 3:</strong></p>
<pre>
<strong>Input:</strong> customers = &quot;YYYY&quot;
<strong>Output:</strong> 4
<strong>Explanation:</strong> It is best to close the shop at the 4<sup>th</sup> hour as customers arrive at each hour.
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= customers.length &lt;= 10<sup>5</sup></code></li>
<li><code>customers</code> consists only of characters <code>&#39;Y&#39;</code> and <code>&#39;N&#39;</code>.</li>
</ul>