Compare commits

..

36 Commits

Author SHA1 Message Date
Deven d998bb39f3 Time: 0 ms (100%), Space: 18.2 MB (28.84%) - LeetHub 2025-11-26 20:57:36 -05:00
Deven a00735fbac Create README - LeetHub 2025-11-26 20:57:36 -05:00
Deven cfa865059f Time: 0 ms (100%), Space: 18 MB (11.85%) - LeetHub 2025-11-26 20:40:36 -05:00
Deven fe1c7f9bab Create README - LeetHub 2025-11-26 20:40:35 -05:00
Deven 102f60b356 Time: 3 ms (44.97%), Space: 17.5 MB (99.61%) - LeetHub 2025-11-26 20:24:25 -05:00
Deven ae638d92a1 Time: 3 ms (44.97%), Space: 17.9 MB (30.12%) - LeetHub 2025-11-26 20:24:19 -05:00
Deven 80347ff593 Time: 3 ms (44.97%), Space: 17.9 MB (30.12%) - LeetHub 2025-11-26 20:16:52 -05:00
Deven 7d5c422e07 Create README - LeetHub 2025-11-26 20:16:52 -05:00
Deven 1b166a19b6 Time: 35 ms (96.78%), Space: 28.7 MB (69.5%) - LeetHub 2025-11-26 20:03:16 -05:00
Deven 5f2c51e273 Time: N/A (0%), Space: N/A (0%) - LeetHub 2025-11-26 20:01:46 -05:00
Deven 16adc41a13 Create README - LeetHub 2025-11-26 20:01:45 -05:00
Deven f6481508e2 Time: 0 ms (100%), Space: 19 MB (94.49%) - LeetHub 2025-11-26 17:18:01 -05:00
Deven 49c8ea6771 Create README - LeetHub 2025-11-26 17:18:01 -05:00
Deven 8208854e3d Time: 3 ms (73%), Space: 17.8 MB (84.61%) - LeetHub 2025-11-26 17:04:38 -05:00
Deven c191441bc1 Create README - LeetHub 2025-11-26 17:04:38 -05:00
Deven 152c8893bd Time: 3 ms (98.34%), Space: 17.9 MB (61.48%) - LeetHub 2025-11-26 16:51:49 -05:00
Deven fa5b9fed70 Time: 3 ms (98.34%), Space: 17.9 MB (61.48%) - LeetHub 2025-11-26 16:48:12 -05:00
Deven 2da1f08a05 Create README - LeetHub 2025-11-26 16:48:12 -05:00
Deven 1f1aa6556e Time: 40 ms (22.41%), Space: 40.9 MB (23.28%) - LeetHub 2025-11-26 15:57:26 -05:00
Deven be925e9060 Time: 40 ms (22.41%), Space: 40.9 MB (23.28%) - LeetHub 2025-11-26 15:49:58 -05:00
Deven 1aef61ac76 Create README - LeetHub 2025-11-26 15:49:58 -05:00
Deven 0d4a52234a Time: 363 ms (42.41%), Space: 17.8 MB (83.35%) - LeetHub 2025-11-26 15:33:48 -05:00
Deven 05038ff089 Time: 5673 ms (9.42%), Space: 17.8 MB (59.54%) - LeetHub 2025-11-26 15:32:56 -05:00
Deven 867399287f Time: 5673 ms (9.42%), Space: 17.8 MB (59.54%) - LeetHub 2025-11-26 15:19:27 -05:00
Deven 72ef28dd40 Create README - LeetHub 2025-11-26 15:19:26 -05:00
Deven b7ad28921e Time: 15 ms (80.93%), Space: 18.1 MB (11.97%) - LeetHub 2025-11-26 15:06:17 -05:00
Deven 7d6e8b17c9 Create README - LeetHub 2025-11-26 15:06:16 -05:00
Deven caf02f8a51 Time: 22 ms (21.01%), Space: 22.7 MB (24.41%) - LeetHub 2025-11-26 14:41:31 -05:00
Deven 6279b72065 Create README - LeetHub 2025-11-26 14:41:30 -05:00
Deven afdd2ae59f Time: 3 ms (71.33%), Space: 18.6 MB (17.59%) - LeetHub 2025-11-26 14:30:06 -05:00
Deven 3399d5f921 Time: 0 ms (100%), Space: 18.6 MB (17.59%) - LeetHub 2025-11-26 14:24:59 -05:00
Deven f6089b1e84 Time: 3 ms (71.33%), Space: 18.2 MB (95.28%) - LeetHub 2025-11-26 13:45:21 -05:00
Deven 7263390db0 Time: 3 ms (71.33%), Space: 18.2 MB (95.28%) - LeetHub 2025-11-26 13:43:48 -05:00
Deven 96785d35cc Create README - LeetHub 2025-11-26 13:43:48 -05:00
Deven c67336bdee Time: 1083 ms (14.78%), Space: 22.4 MB (5.02%) - LeetHub 2025-11-26 13:36:04 -05:00
Deven ff7a4d54ab Create README - LeetHub 2025-11-26 13:36:04 -05:00
26 changed files with 1034 additions and 0 deletions
@@ -0,0 +1,49 @@
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
"""
Complexities:
Time: O(n)
Space: O(1)
where n = max(len(l1), len(l2))
"""
# Addition by place value
currNode1 = l1
currNode2 = l2
sumNode = None
tailNode = None
carry = 0
placeValue = 1
# Loop through nodes until reached end of both lists
while currNode1 or currNode2:
v1 = currNode1.val if currNode1 else 0
v2 = currNode2.val if currNode2 else 0
sumVal = (v1 + v2 + carry) * placeValue
val = sumVal % 10
carry = sumVal // 10
newNode = ListNode(val)
if sumNode == None:
sumNode = newNode
else:
tailNode.next = newNode
tailNode = newNode
currNode1 = currNode1.next if currNode1 else None
currNode2 = currNode2.next if currNode2 else None
if carry:
tailNode.next = ListNode(carry)
return sumNode or ListNode(0)
+35
View File
@@ -0,0 +1,35 @@
<h2><a href="https://leetcode.com/problems/add-two-numbers">2. Add Two Numbers</a></h2><h3>Medium</h3><hr><p>You are given two <strong>non-empty</strong> linked lists representing two non-negative integers. The digits are stored in <strong>reverse order</strong>, and each of their nodes contains a single digit. Add the two numbers and return the sum&nbsp;as a linked list.</p>
<p>You may assume the two numbers do not contain any leading zero, except the number 0 itself.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/10/02/addtwonumber1.jpg" style="width: 483px; height: 342px;" />
<pre>
<strong>Input:</strong> l1 = [2,4,3], l2 = [5,6,4]
<strong>Output:</strong> [7,0,8]
<strong>Explanation:</strong> 342 + 465 = 807.
</pre>
<p><strong class="example">Example 2:</strong></p>
<pre>
<strong>Input:</strong> l1 = [0], l2 = [0]
<strong>Output:</strong> [0]
</pre>
<p><strong class="example">Example 3:</strong></p>
<pre>
<strong>Input:</strong> l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
<strong>Output:</strong> [8,9,9,9,0,0,0,1]
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li>The number of nodes in each linked list is in the range <code>[1, 100]</code>.</li>
<li><code>0 &lt;= Node.val &lt;= 9</code></li>
<li>It is guaranteed that the list represents a number that does not have leading zeros.</li>
</ul>
@@ -0,0 +1,40 @@
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
"""
Complexities:
Time: O(n)
Space: O(X)
where n = len(s)
X = len([All compatible characters])
"""
charsInSubstring = set({})
startIndex = 0 # inclusive
endIndex = 0 # exclusive
maxLengthFound = 0
# Use sliding window to find solution
# - O(n) -> startIndex or endIndex always increase by 1 every iteration = 2n
while endIndex < len(s):
# if next letter not in substring, then endIndex++
if s[endIndex] not in charsInSubstring:
charsInSubstring.add(s[endIndex])
endIndex += 1
# Update maxLengthFound
if endIndex - startIndex > maxLengthFound:
maxLengthFound = endIndex - startIndex
# else pop off front until popped [next letter]
else:
while s[startIndex] != s[endIndex]:
charsInSubstring.remove(s[startIndex])
startIndex += 1
charsInSubstring.remove(s[startIndex])
startIndex += 1
return maxLengthFound
@@ -0,0 +1,35 @@
<h2><a href="https://leetcode.com/problems/longest-substring-without-repeating-characters">3. Longest Substring Without Repeating Characters</a></h2><h3>Medium</h3><hr><p>Given a string <code>s</code>, find the length of the <strong>longest</strong> <span data-keyword="substring-nonempty"><strong>substring</strong></span> without duplicate characters.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre>
<strong>Input:</strong> s = &quot;abcabcbb&quot;
<strong>Output:</strong> 3
<strong>Explanation:</strong> The answer is &quot;abc&quot;, with the length of 3. Note that <code>&quot;bca&quot;</code> and <code>&quot;cab&quot;</code> are also correct answers.
</pre>
<p><strong class="example">Example 2:</strong></p>
<pre>
<strong>Input:</strong> s = &quot;bbbbb&quot;
<strong>Output:</strong> 1
<strong>Explanation:</strong> The answer is &quot;b&quot;, with the length of 1.
</pre>
<p><strong class="example">Example 3:</strong></p>
<pre>
<strong>Input:</strong> s = &quot;pwwkew&quot;
<strong>Output:</strong> 3
<strong>Explanation:</strong> The answer is &quot;wke&quot;, with the length of 3.
Notice that the answer must be a substring, &quot;pwke&quot; is a subsequence and not a substring.
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>0 &lt;= s.length &lt;= 5 * 10<sup>4</sup></code></li>
<li><code>s</code> consists of English letters, digits, symbols and spaces.</li>
</ul>
@@ -0,0 +1,41 @@
class Solution:
def longestPalindrome(self, s: str) -> str:
"""
Complexities:
Time: O(n^2)
Space: O(1)
where n = len(s)
"""
# Returns the longest palindrome centered at s[i] or (s[i], s[i + 1])
# - O(n)
def longestPalindromeFromCenter(i: int, evenCentered: bool):
offset = 1
evenOffset = 1 if evenCentered else 0
while i - offset >= 0 and i + offset + evenOffset < len(s) and s[i - offset] == s[i + offset + evenOffset]:
offset += 1
offset -= 1 # Account for off-by-one
return s[i - offset : i + offset + evenOffset + 1]
maxPalindrome = s[0]
# For each letter, check if it is the center of a palindrome (or center with s[i+1])
# - O(n^2) = n * 2(O(n))
for i in range(len(s)):
# Check for an even length palindrome
if i + 1 < len(s) and s[i] == s[i+1]:
evenPalindrome = longestPalindromeFromCenter(i, True)
if len(evenPalindrome) > len(maxPalindrome):
maxPalindrome = evenPalindrome
oddPalindrome = longestPalindromeFromCenter(i, False)
if len(oddPalindrome) > len(maxPalindrome):
maxPalindrome = oddPalindrome
return maxPalindrome
@@ -0,0 +1,25 @@
<h2><a href="https://leetcode.com/problems/longest-palindromic-substring">5. Longest Palindromic Substring</a></h2><h3>Medium</h3><hr><p>Given a string <code>s</code>, return <em>the longest</em> <span data-keyword="palindromic-string"><em>palindromic</em></span> <span data-keyword="substring-nonempty"><em>substring</em></span> in <code>s</code>.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre>
<strong>Input:</strong> s = &quot;babad&quot;
<strong>Output:</strong> &quot;bab&quot;
<strong>Explanation:</strong> &quot;aba&quot; is also a valid answer.
</pre>
<p><strong class="example">Example 2:</strong></p>
<pre>
<strong>Input:</strong> s = &quot;cbbd&quot;
<strong>Output:</strong> &quot;bb&quot;
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= s.length &lt;= 1000</code></li>
<li><code>s</code> consist of only digits and English letters.</li>
</ul>
+54
View File
@@ -0,0 +1,54 @@
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
# store frequency counts O(n)
frequencies = {}
for num in nums:
frequencies[num] = frequencies.get(num, 0) + 1
# find all pairs O(n^2)
tripleSet = set()
def addTriple(x,y,z): # O(1) *sort always on 3 items
triple = [x, y, z]
triple.sort()
tripleSet.add(tuple(triple))
freq_keys = list(frequencies.keys())
for i in range(len(freq_keys)):
for j in range(i, len(freq_keys)):
if i == j and frequencies[freq_keys[i]] < 2:
continue
pair = [freq_keys[i], freq_keys[j]]
needed = -(pair[0] + pair[1])
# - check for third in frequency counts O(1)
if frequencies.get(needed, -1) == -1:
# no triple for given pair
continue
elif needed == pair[0] or needed == pair[1]:
if pair[0] == pair[1]:
if frequencies[needed] > 2:
addTriple(pair[0], pair[1], needed)
elif frequencies[needed] > 1:
addTriple(pair[0], pair[1], needed)
else:
addTriple(pair[0], pair[1], needed)
return list(map(lambda tup: list(tup), tripleSet))
"""
O(n^3) *too slow
triples = set()
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
for k in range(j + 1, len(nums)):
if nums[i] + nums[j] + nums[k] == 0:
t = [nums[i], nums[j], nums[k]]
t.sort()
triples.add(tuple(t))
return list(map(lambda tup: list(tup), triples))
"""
+41
View File
@@ -0,0 +1,41 @@
<h2><a href="https://leetcode.com/problems/3sum">15. 3Sum</a></h2><h3>Medium</h3><hr><p>Given an integer array nums, return all the triplets <code>[nums[i], nums[j], nums[k]]</code> such that <code>i != j</code>, <code>i != k</code>, and <code>j != k</code>, and <code>nums[i] + nums[j] + nums[k] == 0</code>.</p>
<p>Notice that the solution set must not contain duplicate triplets.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre>
<strong>Input:</strong> nums = [-1,0,1,2,-1,-4]
<strong>Output:</strong> [[-1,-1,2],[-1,0,1]]
<strong>Explanation:</strong>
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.
The distinct triplets are [-1,0,1] and [-1,-1,2].
Notice that the order of the output and the order of the triplets does not matter.
</pre>
<p><strong class="example">Example 2:</strong></p>
<pre>
<strong>Input:</strong> nums = [0,1,1]
<strong>Output:</strong> []
<strong>Explanation:</strong> The only possible triplet does not sum up to 0.
</pre>
<p><strong class="example">Example 3:</strong></p>
<pre>
<strong>Input:</strong> nums = [0,0,0]
<strong>Output:</strong> [[0,0,0]]
<strong>Explanation:</strong> The only possible triplet sums up to 0.
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>3 &lt;= nums.length &lt;= 3000</code></li>
<li><code>-10<sup>5</sup> &lt;= nums[i] &lt;= 10<sup>5</sup></code></li>
</ul>
+33
View File
@@ -0,0 +1,33 @@
class Solution:
def countAndSay(self, n: int) -> str:
"""
Complexities:
Time: O(n2^n)
Space: O()
"""
# O(len(s)) where len(s) ~ O(2^n)
def RLE(s: str) -> str:
rle = ""
checkChar = s[0]
charCount = 0
for i, l in enumerate(s):
if checkChar == l:
charCount += 1
else:
rle += f"{charCount}{checkChar}"
checkChar = l
charCount = 1
if checkChar:
rle += f"{charCount}{checkChar}"
return rle
lastSol = "1"
# Iteratively call RLE on lastSol (equiv. to countAndSay(n-1))
# - O(n2^n) = n * O(2^n)
for i in range(2, n + 1):
lastSol = RLE(lastSol)
return lastSol
+50
View File
@@ -0,0 +1,50 @@
<h2><a href="https://leetcode.com/problems/count-and-say">38. Count and Say</a></h2><h3>Medium</h3><hr><p>The <strong>count-and-say</strong> sequence is a sequence of digit strings defined by the recursive formula:</p>
<ul>
<li><code>countAndSay(1) = &quot;1&quot;</code></li>
<li><code>countAndSay(n)</code> is the run-length encoding of <code>countAndSay(n - 1)</code>.</li>
</ul>
<p><a href="http://en.wikipedia.org/wiki/Run-length_encoding" target="_blank">Run-length encoding</a> (RLE) is a string compression method that works by replacing consecutive identical characters (repeated 2 or more times) with the concatenation of the character and the number marking the count of the characters (length of the run). For example, to compress the string <code>&quot;3322251&quot;</code> we replace <code>&quot;33&quot;</code> with <code>&quot;23&quot;</code>, replace <code>&quot;222&quot;</code> with <code>&quot;32&quot;</code>, replace <code>&quot;5&quot;</code> with <code>&quot;15&quot;</code> and replace <code>&quot;1&quot;</code> with <code>&quot;11&quot;</code>. Thus the compressed string becomes <code>&quot;23321511&quot;</code>.</p>
<p>Given a positive integer <code>n</code>, return <em>the </em><code>n<sup>th</sup></code><em> element of the <strong>count-and-say</strong> sequence</em>.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">n = 4</span></p>
<p><strong>Output:</strong> <span class="example-io">&quot;1211&quot;</span></p>
<p><strong>Explanation:</strong></p>
<pre>
countAndSay(1) = &quot;1&quot;
countAndSay(2) = RLE of &quot;1&quot; = &quot;11&quot;
countAndSay(3) = RLE of &quot;11&quot; = &quot;21&quot;
countAndSay(4) = RLE of &quot;21&quot; = &quot;1211&quot;
</pre>
</div>
<p><strong class="example">Example 2:</strong></p>
<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">n = 1</span></p>
<p><strong>Output:</strong> <span class="example-io">&quot;1&quot;</span></p>
<p><strong>Explanation:</strong></p>
<p>This is the base case.</p>
</div>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= n &lt;= 30</code></li>
</ul>
<p>&nbsp;</p>
<strong>Follow up:</strong> Could you solve it iteratively?
@@ -0,0 +1,31 @@
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
"""
Complexities
Time: O(Mn)
Space: O(n)
where n = len(strs)
M = max(len(str[i])
"""
# Store strs in dictionary, keyed by sorted string (or frequency count)
strsByAnagram = dict({})
# Conversion helper - O(M)
def toFreqTuple(s: str):
freq = [0] * 26
for l in s:
letter_index = ord(l) - ord('a')
freq[letter_index] += 1
return tuple(freq)
# Map each s in str to its key - O(Mn)
for s in strs:
key = toFreqTuple(s)
strsByAnagram[key] = [*strsByAnagram.get(key, []), s]
# Convert dict to array to return - O(n)
return list(strsByAnagram.values())
+43
View File
@@ -0,0 +1,43 @@
<h2><a href="https://leetcode.com/problems/group-anagrams">49. Group Anagrams</a></h2><h3>Medium</h3><hr><p>Given an array of strings <code>strs</code>, group the <span data-keyword="anagram">anagrams</span> together. You can return the answer in <strong>any order</strong>.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">strs = [&quot;eat&quot;,&quot;tea&quot;,&quot;tan&quot;,&quot;ate&quot;,&quot;nat&quot;,&quot;bat&quot;]</span></p>
<p><strong>Output:</strong> <span class="example-io">[[&quot;bat&quot;],[&quot;nat&quot;,&quot;tan&quot;],[&quot;ate&quot;,&quot;eat&quot;,&quot;tea&quot;]]</span></p>
<p><strong>Explanation:</strong></p>
<ul>
<li>There is no string in strs that can be rearranged to form <code>&quot;bat&quot;</code>.</li>
<li>The strings <code>&quot;nat&quot;</code> and <code>&quot;tan&quot;</code> are anagrams as they can be rearranged to form each other.</li>
<li>The strings <code>&quot;ate&quot;</code>, <code>&quot;eat&quot;</code>, and <code>&quot;tea&quot;</code> are anagrams as they can be rearranged to form each other.</li>
</ul>
</div>
<p><strong class="example">Example 2:</strong></p>
<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">strs = [&quot;&quot;]</span></p>
<p><strong>Output:</strong> <span class="example-io">[[&quot;&quot;]]</span></p>
</div>
<p><strong class="example">Example 3:</strong></p>
<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">strs = [&quot;a&quot;]</span></p>
<p><strong>Output:</strong> <span class="example-io">[[&quot;a&quot;]]</span></p>
</div>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= strs.length &lt;= 10<sup>4</sup></code></li>
<li><code>0 &lt;= strs[i].length &lt;= 100</code></li>
<li><code>strs[i]</code> consists of lowercase English letters.</li>
</ul>
@@ -0,0 +1,63 @@
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
# Total complexities:
# O(mn) time
# O(1) space
# Prepare first row/col for marking
firstEntry = matrix[0][0]
# - use m[0][0] as indicator for first row and col
NO_ZEROES_IN_FIRST_ROW_OR_COL = 1
ZERO_IN_FIRST_ROW = 2
ZERO_IN_FIRST_COL = 3
ZERO_IN_FIRST_ROW_AND_COL = 4
matrix[0][0] = NO_ZEROES_IN_FIRST_ROW_OR_COL
if firstEntry == 0:
matrix[0][0] = ZERO_IN_FIRST_ROW_AND_COL
else:
print(f"cp0")
# Search first col for 0s - O(n)
for i in range(1, len(matrix)):
print(f"cp1")
if matrix[i][0] == 0:
matrix[0][0] = ZERO_IN_FIRST_COL
break
# Search first row for 0s - O(m)
for j in range(1, len(matrix[0])):
if matrix[0][j] == 0:
if matrix[0][0] == ZERO_IN_FIRST_COL:
matrix[0][0] = ZERO_IN_FIRST_ROW_AND_COL
else:
matrix[0][0] = ZERO_IN_FIRST_ROW
break
# Find all zeros outside the first row/col - O(mn)
for i in range(1, len(matrix)):
for j in range(1, len(matrix[i])):
if matrix[i][j] == 0:
# Use the first row/col as markers
matrix[i][0] = 0
matrix[0][j] = 0
# Zero center as needed - O(mn)
for i in range(1, len(matrix)):
for j in range(1, len(matrix[i])):
if matrix[i][0] == 0 or matrix[0][j] == 0:
matrix[i][j] = 0
# Set first row/col if needed
if matrix[0][0] == ZERO_IN_FIRST_ROW or matrix[0][0] == ZERO_IN_FIRST_ROW_AND_COL:
for j in range(1, len(matrix[0])):
matrix[0][j] = 0
if matrix[0][0] == ZERO_IN_FIRST_COL or matrix[0][0] == ZERO_IN_FIRST_ROW_AND_COL:
for i in range(1, len(matrix)):
matrix[i][0] = 0
matrix[0][0] = firstEntry if matrix[0][0] == NO_ZEROES_IN_FIRST_ROW_OR_COL else 0
+37
View File
@@ -0,0 +1,37 @@
<h2><a href="https://leetcode.com/problems/set-matrix-zeroes">73. Set Matrix Zeroes</a></h2><h3>Medium</h3><hr><p>Given an <code>m x n</code> integer matrix <code>matrix</code>, if an element is <code>0</code>, set its entire row and column to <code>0</code>&#39;s.</p>
<p>You must do it <a href="https://en.wikipedia.org/wiki/In-place_algorithm" target="_blank">in place</a>.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/08/17/mat1.jpg" style="width: 450px; height: 169px;" />
<pre>
<strong>Input:</strong> matrix = [[1,1,1],[1,0,1],[1,1,1]]
<strong>Output:</strong> [[1,0,1],[0,0,0],[1,0,1]]
</pre>
<p><strong class="example">Example 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/08/17/mat2.jpg" style="width: 450px; height: 137px;" />
<pre>
<strong>Input:</strong> matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
<strong>Output:</strong> [[0,0,0,0],[0,4,5,0],[0,3,1,0]]
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>m == matrix.length</code></li>
<li><code>n == matrix[0].length</code></li>
<li><code>1 &lt;= m, n &lt;= 200</code></li>
<li><code>-2<sup>31</sup> &lt;= matrix[i][j] &lt;= 2<sup>31</sup> - 1</code></li>
</ul>
<p>&nbsp;</p>
<p><strong>Follow up:</strong></p>
<ul>
<li>A straightforward solution using <code>O(mn)</code> space is probably a bad idea.</li>
<li>A simple improvement uses <code>O(m + n)</code> space, but still not the best solution.</li>
<li>Could you devise a constant space solution?</li>
</ul>
@@ -0,0 +1,29 @@
# 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
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
"""
Complexities:
Time: O(n)
Space: O(n)
where n = total node in graph
"""
if not root:
return []
arr = []
if root.left:
arr += self.inorderTraversal(root.left)
arr += [root.val]
if root.right:
arr += self.inorderTraversal(root.right)
return arr
@@ -0,0 +1,53 @@
<h2><a href="https://leetcode.com/problems/binary-tree-inorder-traversal">94. Binary Tree Inorder Traversal</a></h2><h3>Easy</h3><hr><p>Given the <code>root</code> of a binary tree, return <em>the inorder traversal of its nodes&#39; values</em>.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">root = [1,null,2,3]</span></p>
<p><strong>Output:</strong> <span class="example-io">[1,3,2]</span></p>
<p><strong>Explanation:</strong></p>
<p><img alt="" src="https://assets.leetcode.com/uploads/2024/08/29/screenshot-2024-08-29-202743.png" style="width: 200px; height: 264px;" /></p>
</div>
<p><strong class="example">Example 2:</strong></p>
<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">root = [1,2,3,4,5,null,8,null,null,6,7,9]</span></p>
<p><strong>Output:</strong> <span class="example-io">[4,2,6,5,7,1,3,9,8]</span></p>
<p><strong>Explanation:</strong></p>
<p><img alt="" src="https://assets.leetcode.com/uploads/2024/08/29/tree_2.png" style="width: 350px; height: 286px;" /></p>
</div>
<p><strong class="example">Example 3:</strong></p>
<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">root = []</span></p>
<p><strong>Output:</strong> <span class="example-io">[]</span></p>
</div>
<p><strong class="example">Example 4:</strong></p>
<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">root = [1]</span></p>
<p><strong>Output:</strong> <span class="example-io">[1]</span></p>
</div>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li>The number of nodes in the tree is in the range <code>[0, 100]</code>.</li>
<li><code>-100 &lt;= Node.val &lt;= 100</code></li>
</ul>
<p>&nbsp;</p>
<strong>Follow up:</strong> Recursive solution is trivial, could you do it iteratively?
@@ -0,0 +1,58 @@
# 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
class Solution:
def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
"""
Complexities:
Time: O(n)
Space: O(n)
where n = number of nodes in graph
"""
if not root:
return []
traversal = [[root]]
hasNextLevel = root.left or root.right
# Store nodes from left to right in arrays by depth - O(n)
while hasNextLevel:
lastLevel = traversal[-1]
nextLevel = []
hasNextLevel = False
for node in lastLevel:
if node.left:
nextLevel.append(node.left)
hasNextLevel = hasNextLevel or bool(node.left.left or node.left.right)
if node.right:
nextLevel.append(node.right)
hasNextLevel = hasNextLevel or bool(node.right.left or node.right.right)
traversal.append(nextLevel)
# Convert nodes to values + reverse every other level - O(n)
valueTraversal = []
for depth, level in enumerate(traversal):
start = 0 if depth % 2 == 0 else len(level) - 1
end = len(level) if depth % 2 == 0 else -1
step = 1 if depth % 2 == 0 else -1
nextLevelValues = []
for i in range(start, end, step):
nextLevelValues.append(level[i].val)
valueTraversal.append(nextLevelValues)
return valueTraversal
@@ -0,0 +1,31 @@
<h2><a href="https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal">103. Binary Tree Zigzag Level Order Traversal</a></h2><h3>Medium</h3><hr><p>Given the <code>root</code> of a binary tree, return <em>the zigzag level order traversal of its nodes&#39; values</em>. (i.e., from left to right, then right to left for the next level and alternate between).</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/02/19/tree1.jpg" style="width: 277px; height: 302px;" />
<pre>
<strong>Input:</strong> root = [3,9,20,null,null,15,7]
<strong>Output:</strong> [[3],[20,9],[15,7]]
</pre>
<p><strong class="example">Example 2:</strong></p>
<pre>
<strong>Input:</strong> root = [1]
<strong>Output:</strong> [[1]]
</pre>
<p><strong class="example">Example 3:</strong></p>
<pre>
<strong>Input:</strong> root = []
<strong>Output:</strong> []
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li>The number of nodes in the tree is in the range <code>[0, 2000]</code>.</li>
<li><code>-100 &lt;= Node.val &lt;= 100</code></li>
</ul>
@@ -0,0 +1,19 @@
import heapq
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
heap = nums[:k]
# Heapify (min) the first k elements
heapq.heapify(heap)
# iterate over k+1...n - O(n) times
# - if larger than min in heap, replace min - O(log k)
# - else do nothing
for i in range(k, len(nums)):
num = nums[i]
if num > heap[0]:
heapq.heapreplace(heap, num)
# return min in heap
return heap[0]
@@ -0,0 +1,21 @@
<h2><a href="https://leetcode.com/problems/kth-largest-element-in-an-array">215. Kth Largest Element in an Array</a></h2><h3>Medium</h3><hr><p>Given an integer array <code>nums</code> and an integer <code>k</code>, return <em>the</em> <code>k<sup>th</sup></code> <em>largest element in the array</em>.</p>
<p>Note that it is the <code>k<sup>th</sup></code> largest element in the sorted order, not the <code>k<sup>th</sup></code> distinct element.</p>
<p>Can you solve it without sorting?</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre><strong>Input:</strong> nums = [3,2,1,5,6,4], k = 2
<strong>Output:</strong> 5
</pre><p><strong class="example">Example 2:</strong></p>
<pre><strong>Input:</strong> nums = [3,2,3,1,2,4,5,5,6], k = 4
<strong>Output:</strong> 4
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= k &lt;= nums.length &lt;= 10<sup>5</sup></code></li>
<li><code>-10<sup>4</sup> &lt;= nums[i] &lt;= 10<sup>4</sup></code></li>
</ul>
@@ -0,0 +1,50 @@
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
"""
Complexities:
Time: O(n)
Space: O(1)
where n = len(head)
"""
# If len(head) <= 2, already sorted
if not head or not head.next:
return head
oddHead = head
oddTail = head
evenHead = head.next
evenTail = head.next
currNode = head.next.next
isOddIndex = True
# Set tail.next = None
oddTail.next = None
evenTail.next = None
# Separate list into odd list and even list
while currNode:
nextNode = currNode.next
currNode.next = None
if isOddIndex:
oddTail.next = currNode
oddTail = currNode
else:
evenTail.next = currNode
evenTail = currNode
currNode = nextNode
isOddIndex = not isOddIndex
# Attach both lists
oddTail.next = evenHead
return oddHead
+30
View File
@@ -0,0 +1,30 @@
<h2><a href="https://leetcode.com/problems/odd-even-linked-list">328. Odd Even Linked List</a></h2><h3>Medium</h3><hr><p>Given the <code>head</code> of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return <em>the reordered list</em>.</p>
<p>The <strong>first</strong> node is considered <strong>odd</strong>, and the <strong>second</strong> node is <strong>even</strong>, and so on.</p>
<p>Note that the relative order inside both the even and odd groups should remain as it was in the input.</p>
<p>You must solve the problem&nbsp;in <code>O(1)</code>&nbsp;extra space complexity and <code>O(n)</code> time complexity.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/03/10/oddeven-linked-list.jpg" style="width: 300px; height: 123px;" />
<pre>
<strong>Input:</strong> head = [1,2,3,4,5]
<strong>Output:</strong> [1,3,5,2,4]
</pre>
<p><strong class="example">Example 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/03/10/oddeven2-linked-list.jpg" style="width: 500px; height: 142px;" />
<pre>
<strong>Input:</strong> head = [2,1,3,5,6,4,7]
<strong>Output:</strong> [2,3,6,7,1,5,4]
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li>The number of nodes in the linked list is in the range <code>[0, 10<sup>4</sup>]</code>.</li>
<li><code>-10<sup>6</sup> &lt;= Node.val &lt;= 10<sup>6</sup></code></li>
</ul>
@@ -0,0 +1,37 @@
class Solution:
def increasingTriplet(self, nums: List[int]) -> bool:
"""
Complexities:
Time: O(n)
Space: O(n)
where n = len(nums)
"""
# Find j candidates (where nums[i] < nums[j])
# - j is not 0
# - nums[j] is not min so far
# --- O(n)
jCandidates = []
minSoFar = nums[0]
for j in range(1, len(nums)):
if nums[j] <= minSoFar:
minSoFar = nums[j]
else:
jCandidates.append(j)
# Fail fast: 0-1 jCandidates = no increasing tuplet (one j candidate will be k)
if len(jCandidates) <= 1:
return False
# Find k candidates (where nums[j] < nums[k])
# - do the same iteration as j but only over j candidates
# --- O(n)
minSoFar = nums[jCandidates[0]]
for kPrime in range(1, len(jCandidates)):
if nums[jCandidates[kPrime]] <= minSoFar:
minSoFar = nums[jCandidates[kPrime]]
else:
return True
return False
@@ -0,0 +1,37 @@
<h2><a href="https://leetcode.com/problems/increasing-triplet-subsequence">334. Increasing Triplet Subsequence</a></h2><h3>Medium</h3><hr><p>Given an integer array <code>nums</code>, return <code>true</code><em> if there exists a triple of indices </em><code>(i, j, k)</code><em> such that </em><code>i &lt; j &lt; k</code><em> and </em><code>nums[i] &lt; nums[j] &lt; nums[k]</code>. If no such indices exists, return <code>false</code>.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre>
<strong>Input:</strong> nums = [1,2,3,4,5]
<strong>Output:</strong> true
<strong>Explanation:</strong> Any triplet where i &lt; j &lt; k is valid.
</pre>
<p><strong class="example">Example 2:</strong></p>
<pre>
<strong>Input:</strong> nums = [5,4,3,2,1]
<strong>Output:</strong> false
<strong>Explanation:</strong> No triplet exists.
</pre>
<p><strong class="example">Example 3:</strong></p>
<pre>
<strong>Input:</strong> nums = [2,1,5,0,4,6]
<strong>Output:</strong> true
<strong>Explanation:</strong> One of the valid triplet is (1, 4, 5), because nums[1] == 1 &lt; nums[4] == 4 &lt; nums[5] == 6.
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= nums.length &lt;= 5 * 10<sup>5</sup></code></li>
<li><code>-2<sup>31</sup> &lt;= nums[i] &lt;= 2<sup>31</sup> - 1</code></li>
</ul>
<p>&nbsp;</p>
<strong>Follow up:</strong> Could you implement a solution that runs in <code>O(n)</code> time complexity and <code>O(1)</code> space complexity?
@@ -0,0 +1,44 @@
class Solution:
def makeGood(self, s: str) -> str:
"""
Complexities:
Time: O(n)
Space: O(n)
where n = len(s)
"""
# base case: len(s) == 1
if len(s) <= 1:
return s
stack = ""
for letter in s:
stack += letter
if len(stack) >= 2 and stack[-2] != stack[-1] and stack[-2].lower() == stack[-1].lower():
stack = stack[:-2]
return stack
"""
# iterate over all letters
# - compare s[i], s[i+1]
# - if I remove, look at s[i-1]
i = 0
while i <= len(s) - 2:
if s[i] != s[i + 1] and s[i].lower() == s[i + 1].lower():
s = s[:i] + s[i+2:]
if i > 0:
i -= 1
else:
i += 1
return s
"""
+48
View File
@@ -0,0 +1,48 @@
<h2><a href="https://leetcode.com/problems/make-the-string-great">1544. Make The String Great</a></h2><h3>Easy</h3><hr><p>Given a string <code>s</code> of lower and upper case English letters.</p>
<p>A good string is a string which doesn&#39;t have <strong>two adjacent characters</strong> <code>s[i]</code> and <code>s[i + 1]</code> where:</p>
<ul>
<li><code>0 &lt;= i &lt;= s.length - 2</code></li>
<li><code>s[i]</code> is a lower-case letter and <code>s[i + 1]</code> is the same letter but in upper-case or <strong>vice-versa</strong>.</li>
</ul>
<p>To make the string good, you can choose <strong>two adjacent</strong> characters that make the string bad and remove them. You can keep doing this until the string becomes good.</p>
<p>Return <em>the string</em> after making it good. The answer is guaranteed to be unique under the given constraints.</p>
<p><strong>Notice</strong> that an empty string is also good.</p>
<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre>
<strong>Input:</strong> s = &quot;leEeetcode&quot;
<strong>Output:</strong> &quot;leetcode&quot;
<strong>Explanation:</strong> In the first step, either you choose i = 1 or i = 2, both will result &quot;leEeetcode&quot; to be reduced to &quot;leetcode&quot;.
</pre>
<p><strong class="example">Example 2:</strong></p>
<pre>
<strong>Input:</strong> s = &quot;abBAcC&quot;
<strong>Output:</strong> &quot;&quot;
<strong>Explanation:</strong> We have many possible scenarios, and all lead to the same answer. For example:
&quot;abBAcC&quot; --&gt; &quot;aAcC&quot; --&gt; &quot;cC&quot; --&gt; &quot;&quot;
&quot;abBAcC&quot; --&gt; &quot;abBA&quot; --&gt; &quot;aA&quot; --&gt; &quot;&quot;
</pre>
<p><strong class="example">Example 3:</strong></p>
<pre>
<strong>Input:</strong> s = &quot;s&quot;
<strong>Output:</strong> &quot;s&quot;
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>
<ul>
<li><code>1 &lt;= s.length &lt;= 100</code></li>
<li><code>s</code> contains only lower and upper case English letters.</li>
</ul>