mirror of
https://github.com/devenperez/leetcode.git
synced 2026-06-15 09:57:09 +00:00
Compare commits
57 Commits
3dd0835a88
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 88b99caf11 | |||
| 2c96c57870 | |||
| 6bc1bcb772 | |||
| f174c1edea | |||
| 3c88ab7152 | |||
| cbef5fb714 | |||
| c45b01a838 | |||
| cc492aa3b2 | |||
| cf8b99d511 | |||
| c90ee7f934 | |||
| 10ff3a0da5 | |||
| 29c783e08b | |||
| 79b324dd16 | |||
| 6e90bcdc1f | |||
| ae4b1056dd | |||
| d5e6259f5b | |||
| c6bc37a26c | |||
| a7dc8f50f0 | |||
| fadfb3c332 | |||
| 45404409de | |||
| 71d9f17be7 | |||
| d998bb39f3 | |||
| a00735fbac | |||
| cfa865059f | |||
| fe1c7f9bab | |||
| 102f60b356 | |||
| ae638d92a1 | |||
| 80347ff593 | |||
| 7d5c422e07 | |||
| 1b166a19b6 | |||
| 5f2c51e273 | |||
| 16adc41a13 | |||
| f6481508e2 | |||
| 49c8ea6771 | |||
| 8208854e3d | |||
| c191441bc1 | |||
| 152c8893bd | |||
| fa5b9fed70 | |||
| 2da1f08a05 | |||
| 1f1aa6556e | |||
| be925e9060 | |||
| 1aef61ac76 | |||
| 0d4a52234a | |||
| 05038ff089 | |||
| 867399287f | |||
| 72ef28dd40 | |||
| b7ad28921e | |||
| 7d6e8b17c9 | |||
| caf02f8a51 | |||
| 6279b72065 | |||
| afdd2ae59f | |||
| 3399d5f921 | |||
| f6089b1e84 | |||
| 7263390db0 | |||
| 96785d35cc | |||
| c67336bdee | |||
| ff7a4d54ab |
@@ -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)
|
||||
|
||||
|
||||
@@ -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 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> </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> </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 <= Node.val <= 9</code></li>
|
||||
<li>It is guaranteed that the list represents a number that does not have leading zeros.</li>
|
||||
</ul>
|
||||
+40
@@ -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> </p>
|
||||
<p><strong class="example">Example 1:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "abcabcbb"
|
||||
<strong>Output:</strong> 3
|
||||
<strong>Explanation:</strong> The answer is "abc", with the length of 3. Note that <code>"bca"</code> and <code>"cab"</code> are also correct answers.
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 2:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "bbbbb"
|
||||
<strong>Output:</strong> 1
|
||||
<strong>Explanation:</strong> The answer is "b", with the length of 1.
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 3:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "pwwkew"
|
||||
<strong>Output:</strong> 3
|
||||
<strong>Explanation:</strong> The answer is "wke", with the length of 3.
|
||||
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>0 <= s.length <= 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> </p>
|
||||
<p><strong class="example">Example 1:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "babad"
|
||||
<strong>Output:</strong> "bab"
|
||||
<strong>Explanation:</strong> "aba" is also a valid answer.
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 2:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "cbbd"
|
||||
<strong>Output:</strong> "bb"
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= s.length <= 1000</code></li>
|
||||
<li><code>s</code> consist of only digits and English letters.</li>
|
||||
</ul>
|
||||
@@ -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))
|
||||
"""
|
||||
@@ -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> </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> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>3 <= nums.length <= 3000</code></li>
|
||||
<li><code>-10<sup>5</sup> <= nums[i] <= 10<sup>5</sup></code></li>
|
||||
</ul>
|
||||
@@ -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
|
||||
@@ -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's nodes, only nodes themselves may be changed.</p>
|
||||
|
||||
<p> </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> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li>The number of nodes in the list is <code>n</code>.</li>
|
||||
<li><code>1 <= k <= n <= 5000</code></li>
|
||||
<li><code>0 <= Node.val <= 1000</code></li>
|
||||
</ul>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Follow-up:</strong> Can you solve the problem in <code>O(1)</code> extra memory space?</p>
|
||||
@@ -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
|
||||
@@ -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) = "1"</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>"3322251"</code> we replace <code>"33"</code> with <code>"23"</code>, replace <code>"222"</code> with <code>"32"</code>, replace <code>"5"</code> with <code>"15"</code> and replace <code>"1"</code> with <code>"11"</code>. Thus the compressed string becomes <code>"23321511"</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> </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">"1211"</span></p>
|
||||
|
||||
<p><strong>Explanation:</strong></p>
|
||||
|
||||
<pre>
|
||||
countAndSay(1) = "1"
|
||||
countAndSay(2) = RLE of "1" = "11"
|
||||
countAndSay(3) = RLE of "11" = "21"
|
||||
countAndSay(4) = RLE of "21" = "1211"
|
||||
</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">"1"</span></p>
|
||||
|
||||
<p><strong>Explanation:</strong></p>
|
||||
|
||||
<p>This is the base case.</p>
|
||||
</div>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= n <= 30</code></li>
|
||||
</ul>
|
||||
|
||||
<p> </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())
|
||||
@@ -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> </p>
|
||||
<p><strong class="example">Example 1:</strong></p>
|
||||
|
||||
<div class="example-block">
|
||||
<p><strong>Input:</strong> <span class="example-io">strs = ["eat","tea","tan","ate","nat","bat"]</span></p>
|
||||
|
||||
<p><strong>Output:</strong> <span class="example-io">[["bat"],["nat","tan"],["ate","eat","tea"]]</span></p>
|
||||
|
||||
<p><strong>Explanation:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li>There is no string in strs that can be rearranged to form <code>"bat"</code>.</li>
|
||||
<li>The strings <code>"nat"</code> and <code>"tan"</code> are anagrams as they can be rearranged to form each other.</li>
|
||||
<li>The strings <code>"ate"</code>, <code>"eat"</code>, and <code>"tea"</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 = [""]</span></p>
|
||||
|
||||
<p><strong>Output:</strong> <span class="example-io">[[""]]</span></p>
|
||||
</div>
|
||||
|
||||
<p><strong class="example">Example 3:</strong></p>
|
||||
|
||||
<div class="example-block">
|
||||
<p><strong>Input:</strong> <span class="example-io">strs = ["a"]</span></p>
|
||||
|
||||
<p><strong>Output:</strong> <span class="example-io">[["a"]]</span></p>
|
||||
</div>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= strs.length <= 10<sup>4</sup></code></li>
|
||||
<li><code>0 <= strs[i].length <= 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
|
||||
@@ -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>'s.</p>
|
||||
|
||||
<p>You must do it <a href="https://en.wikipedia.org/wiki/In-place_algorithm" target="_blank">in place</a>.</p>
|
||||
|
||||
<p> </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> </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 <= m, n <= 200</code></li>
|
||||
<li><code>-2<sup>31</sup> <= matrix[i][j] <= 2<sup>31</sup> - 1</code></li>
|
||||
</ul>
|
||||
|
||||
<p> </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' values</em>.</p>
|
||||
|
||||
<p> </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> </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 <= Node.val <= 100</code></li>
|
||||
</ul>
|
||||
|
||||
<p> </p>
|
||||
<strong>Follow up:</strong> Recursive solution is trivial, could you do it iteratively?
|
||||
+58
@@ -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' values</em>. (i.e., from left to right, then right to left for the next level and alternate between).</p>
|
||||
|
||||
<p> </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> </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 <= Node.val <= 100</code></li>
|
||||
</ul>
|
||||
@@ -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
|
||||
|
||||
@@ -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<Node> neighbors;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<p><strong>Test case format:</strong></p>
|
||||
|
||||
<p>For simplicity, each node's value is the same as the node'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> </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)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
|
||||
2nd node (val = 2)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
|
||||
3rd node (val = 3)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
|
||||
4th node (val = 4)'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> </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 <= Node.val <= 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,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> </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> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= k <= nums.length <= 10<sup>5</sup></code></li>
|
||||
<li><code>-10<sup>4</sup> <= nums[i] <= 10<sup>4</sup></code></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
|
||||
|
||||
@@ -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>. </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> </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> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= s.length <= 3 * 10<sup>5</sup></code></li>
|
||||
<li><code>s</code> consists of integers and operators <code>('+', '-', '*', '/')</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>
|
||||
@@ -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]
|
||||
@@ -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> </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> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= coins.length <= 12</code></li>
|
||||
<li><code>1 <= coins[i] <= 2<sup>31</sup> - 1</code></li>
|
||||
<li><code>0 <= amount <= 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
|
||||
@@ -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 in <code>O(1)</code> extra space complexity and <code>O(n)</code> time complexity.</p>
|
||||
|
||||
<p> </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> </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> <= Node.val <= 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 < j < k</code><em> and </em><code>nums[i] < nums[j] < nums[k]</code>. If no such indices exists, return <code>false</code>.</p>
|
||||
|
||||
<p> </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 < j < 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 < nums[4] == 4 < nums[5] == 6.
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= nums.length <= 5 * 10<sup>5</sup></code></li>
|
||||
<li><code>-2<sup>31</sup> <= nums[i] <= 2<sup>31</sup> - 1</code></li>
|
||||
</ul>
|
||||
|
||||
<p> </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,84 @@
|
||||
# """
|
||||
# This is the interface that allows for creating nested lists.
|
||||
# You should not implement it, or speculate about its implementation
|
||||
# """
|
||||
#class NestedInteger:
|
||||
# def __init__(self, value=None):
|
||||
# """
|
||||
# If value is not specified, initializes an empty list.
|
||||
# Otherwise initializes a single integer equal to value.
|
||||
# """
|
||||
#
|
||||
# def isInteger(self):
|
||||
# """
|
||||
# @return True if this NestedInteger holds a single integer, rather than a nested list.
|
||||
# :rtype bool
|
||||
# """
|
||||
#
|
||||
# def add(self, elem):
|
||||
# """
|
||||
# Set this NestedInteger to hold a nested list and adds a nested integer elem to it.
|
||||
# :rtype void
|
||||
# """
|
||||
#
|
||||
# def setInteger(self, value):
|
||||
# """
|
||||
# Set this NestedInteger to hold a single integer equal to value.
|
||||
# :rtype void
|
||||
# """
|
||||
#
|
||||
# def getInteger(self):
|
||||
# """
|
||||
# @return the single integer that this NestedInteger holds, if it holds a single integer
|
||||
# Return None if this NestedInteger holds a nested list
|
||||
# :rtype int
|
||||
# """
|
||||
#
|
||||
# def getList(self):
|
||||
# """
|
||||
# @return the nested list that this NestedInteger holds, if it holds a nested list
|
||||
# Return None if this NestedInteger holds a single integer
|
||||
# :rtype List[NestedInteger]
|
||||
# """
|
||||
|
||||
class Solution:
|
||||
def deserialize(self, s: str) -> NestedInteger:
|
||||
"""
|
||||
Complexities:
|
||||
Time: O(n)
|
||||
Space: O(n)
|
||||
|
||||
where n = len(s)
|
||||
"""
|
||||
|
||||
# base case: number
|
||||
if s[0] != "[":
|
||||
return NestedInteger(int(s))
|
||||
|
||||
# is a list
|
||||
head = NestedInteger()
|
||||
stack = [head]
|
||||
|
||||
i = 1
|
||||
while i < len(s):
|
||||
if s[i] == ",":
|
||||
i += 1
|
||||
elif s[i] == "[":
|
||||
newNestedInteger = NestedInteger()
|
||||
stack[-1].add(newNestedInteger)
|
||||
stack.append(newNestedInteger)
|
||||
i += 1
|
||||
elif s[i] == "]":
|
||||
stack.pop()
|
||||
i += 1
|
||||
else: # Is number or '-'
|
||||
# Find entire number
|
||||
j = i
|
||||
while s[j] not in ",]":
|
||||
j += 1
|
||||
newInt = int(s[i:j])
|
||||
stack[-1].add(NestedInteger(newInt))
|
||||
i = j
|
||||
|
||||
return head
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<h2><a href="https://leetcode.com/problems/mini-parser">385. Mini Parser</a></h2><h3>Medium</h3><hr><p>Given a string s represents the serialization of a nested list, implement a parser to deserialize it and return <em>the deserialized</em> <code>NestedInteger</code>.</p>
|
||||
|
||||
<p>Each element is either an integer or a list whose elements may also be integers or other lists.</p>
|
||||
|
||||
<p> </p>
|
||||
<p><strong class="example">Example 1:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "324"
|
||||
<strong>Output:</strong> 324
|
||||
<strong>Explanation:</strong> You should return a NestedInteger object which contains a single integer 324.
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 2:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "[123,[456,[789]]]"
|
||||
<strong>Output:</strong> [123,[456,[789]]]
|
||||
<strong>Explanation:</strong> Return a NestedInteger object containing a nested list with 2 elements:
|
||||
1. An integer containing value 123.
|
||||
2. A nested list containing two elements:
|
||||
i. An integer containing value 456.
|
||||
ii. A nested list with one element:
|
||||
a. An integer containing value 789
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= s.length <= 5 * 10<sup>4</sup></code></li>
|
||||
<li><code>s</code> consists of digits, square brackets <code>"[]"</code>, negative sign <code>'-'</code>, and commas <code>','</code>.</li>
|
||||
<li><code>s</code> is the serialization of valid <code>NestedInteger</code>.</li>
|
||||
<li>All the values in the input are in the range <code>[-10<sup>6</sup>, 10<sup>6</sup>]</code>.</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,61 @@
|
||||
class Solution:
|
||||
def checkValidString(self, s: str) -> bool:
|
||||
"""
|
||||
Complexities:
|
||||
Time: O(n)
|
||||
Space: O(n)
|
||||
|
||||
where n = len(s)
|
||||
"""
|
||||
|
||||
bracketCount = 0
|
||||
starCount = 0
|
||||
starIndecies = []
|
||||
usedStars = 0
|
||||
|
||||
# Forward pass - allocate as many *s to be (
|
||||
# - when allocating a star, always use the star that appears first
|
||||
for i, l in enumerate(s):
|
||||
if l == '(':
|
||||
bracketCount += 1
|
||||
elif l == '*':
|
||||
starCount += 1
|
||||
starIndecies.append(i)
|
||||
elif bracketCount > 0:
|
||||
bracketCount -= 1
|
||||
elif starCount > 0:
|
||||
starCount -= 1
|
||||
usedStars += 1
|
||||
else:
|
||||
return False
|
||||
|
||||
# There are already matching opening/closing brackets
|
||||
# - all stars are assigned empty string
|
||||
if bracketCount == 0:
|
||||
return True
|
||||
|
||||
# There are more closed brackets needed than the amount of remaining stars
|
||||
if bracketCount > 0 and bracketCount > starCount:
|
||||
return False
|
||||
|
||||
# Backward pass - allocate as many *s to be )
|
||||
# - the first `usedStars` stars are considered used from the forward pass
|
||||
firstViableStar = starIndecies[usedStars]
|
||||
bracketCount = 0
|
||||
starCount = 0
|
||||
for i in range(len(s) - 1, 0, -1):
|
||||
l = s[i]
|
||||
|
||||
if l == ')':
|
||||
bracketCount += 1
|
||||
elif l == '*':
|
||||
starCount += 1 if i >= firstViableStar else 0
|
||||
elif bracketCount > 0:
|
||||
bracketCount -= 1
|
||||
elif starCount > 0:
|
||||
starIndecies.pop(0)
|
||||
starCount -= 1
|
||||
else:
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -0,0 +1,29 @@
|
||||
<h2><a href="https://leetcode.com/problems/valid-parenthesis-string">678. Valid Parenthesis String</a></h2><h3>Medium</h3><hr><p>Given a string <code>s</code> containing only three types of characters: <code>'('</code>, <code>')'</code> and <code>'*'</code>, return <code>true</code> <em>if</em> <code>s</code> <em>is <strong>valid</strong></em>.</p>
|
||||
|
||||
<p>The following rules define a <strong>valid</strong> string:</p>
|
||||
|
||||
<ul>
|
||||
<li>Any left parenthesis <code>'('</code> must have a corresponding right parenthesis <code>')'</code>.</li>
|
||||
<li>Any right parenthesis <code>')'</code> must have a corresponding left parenthesis <code>'('</code>.</li>
|
||||
<li>Left parenthesis <code>'('</code> must go before the corresponding right parenthesis <code>')'</code>.</li>
|
||||
<li><code>'*'</code> could be treated as a single right parenthesis <code>')'</code> or a single left parenthesis <code>'('</code> or an empty string <code>""</code>.</li>
|
||||
</ul>
|
||||
|
||||
<p> </p>
|
||||
<p><strong class="example">Example 1:</strong></p>
|
||||
<pre><strong>Input:</strong> s = "()"
|
||||
<strong>Output:</strong> true
|
||||
</pre><p><strong class="example">Example 2:</strong></p>
|
||||
<pre><strong>Input:</strong> s = "(*)"
|
||||
<strong>Output:</strong> true
|
||||
</pre><p><strong class="example">Example 3:</strong></p>
|
||||
<pre><strong>Input:</strong> s = "(*))"
|
||||
<strong>Output:</strong> true
|
||||
</pre>
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= s.length <= 100</code></li>
|
||||
<li><code>s[i]</code> is <code>'('</code>, <code>')'</code> or <code>'*'</code>.</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,37 @@
|
||||
class Solution:
|
||||
def asteroidCollision(self, asteroids: List[int]) -> List[int]:
|
||||
"""
|
||||
Complexities:
|
||||
Time: O(n)
|
||||
Space: O(n)
|
||||
|
||||
where n = len(asteroids)
|
||||
"""
|
||||
|
||||
# iterate left to right
|
||||
# - if right (+ve), keep stack
|
||||
# - if left (-ve), compare/consume top of stack
|
||||
# - - if left consume all of stack, add to output (it will survive)
|
||||
|
||||
stack = []
|
||||
survivedAsteroids = []
|
||||
for i in range(len(asteroids)):
|
||||
if asteroids[i] > 0:
|
||||
stack.append(asteroids[i])
|
||||
else:
|
||||
isDestroyed = False
|
||||
while len(stack) > 0 and abs(asteroids[i]) >= stack[-1]:
|
||||
if abs(asteroids[i]) == stack[-1]:
|
||||
isDestroyed = True
|
||||
stack.pop()
|
||||
break
|
||||
stack.pop()
|
||||
|
||||
if len(stack) == 0 and not isDestroyed:
|
||||
survivedAsteroids.append(asteroids[i])
|
||||
|
||||
|
||||
# also return stack
|
||||
survivedAsteroids += stack
|
||||
|
||||
return survivedAsteroids
|
||||
@@ -0,0 +1,47 @@
|
||||
<h2><a href="https://leetcode.com/problems/asteroid-collision">735. Asteroid Collision</a></h2><h3>Medium</h3><hr><p>We are given an array <code>asteroids</code> of integers representing asteroids in a row. The indices of the asteroid in the array represent their relative position in space.</p>
|
||||
|
||||
<p>For each asteroid, the absolute value represents its size, and the sign represents its direction (positive meaning right, negative meaning left). Each asteroid moves at the same speed.</p>
|
||||
|
||||
<p>Find out the state of the asteroids after all collisions. If two asteroids meet, the smaller one will explode. If both are the same size, both will explode. Two asteroids moving in the same direction will never meet.</p>
|
||||
|
||||
<p> </p>
|
||||
<p><strong class="example">Example 1:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> asteroids = [5,10,-5]
|
||||
<strong>Output:</strong> [5,10]
|
||||
<strong>Explanation:</strong> The 10 and -5 collide resulting in 10. The 5 and 10 never collide.
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 2:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> asteroids = [8,-8]
|
||||
<strong>Output:</strong> []
|
||||
<strong>Explanation:</strong> The 8 and -8 collide exploding each other.
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 3:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> asteroids = [10,2,-5]
|
||||
<strong>Output:</strong> [10]
|
||||
<strong>Explanation:</strong> The 2 and -5 collide resulting in -5. The 10 and -5 collide resulting in 10.
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 4:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> asteroids = [3,5,-6,2,-1,4]
|
||||
<strong>Output:</strong> [-6,2,4]
|
||||
<strong>Explanation:</strong> The asteroid -6 makes the asteroid 3 and 5 explode, and then continues going left. On the other side, the asteroid 2 makes the asteroid -1 explode and then continues going right, without reaching asteroid 4.
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>2 <= asteroids.length <= 10<sup>4</sup></code></li>
|
||||
<li><code>-1000 <= asteroids[i] <= 1000</code></li>
|
||||
<li><code>asteroids[i] != 0</code></li>
|
||||
</ul>
|
||||
@@ -0,0 +1,32 @@
|
||||
class Solution:
|
||||
def deckRevealedIncreasing(self, deck: List[int]) -> List[int]:
|
||||
"""
|
||||
Complexities:
|
||||
Time: O(n^2)
|
||||
Space: O(n)
|
||||
|
||||
where n = len(deck)
|
||||
"""
|
||||
# run through a sample deck, save ordering
|
||||
sample = [i for i in range(len(deck))]
|
||||
|
||||
revealedCards = []
|
||||
while len(revealedCards) < len(deck):
|
||||
revealedCards.append(sample[0])
|
||||
sample.pop(0)
|
||||
|
||||
if len(sample) == 0:
|
||||
break
|
||||
|
||||
sample.append(sample[0])
|
||||
sample.pop(0)
|
||||
|
||||
# sort deck
|
||||
deck.sort()
|
||||
|
||||
# replace sample with deck values
|
||||
returnedArr = [-1] * len(deck)
|
||||
for i in range(len(revealedCards)):
|
||||
returnedArr[revealedCards[i]] = deck[i]
|
||||
|
||||
return returnedArr
|
||||
@@ -0,0 +1,50 @@
|
||||
<h2><a href="https://leetcode.com/problems/reveal-cards-in-increasing-order">950. Reveal Cards In Increasing Order</a></h2><h3>Medium</h3><hr><p>You are given an integer array <code>deck</code>. There is a deck of cards where every card has a unique integer. The integer on the <code>i<sup>th</sup></code> card is <code>deck[i]</code>.</p>
|
||||
|
||||
<p>You can order the deck in any order you want. Initially, all the cards start face down (unrevealed) in one deck.</p>
|
||||
|
||||
<p>You will do the following steps repeatedly until all cards are revealed:</p>
|
||||
|
||||
<ol>
|
||||
<li>Take the top card of the deck, reveal it, and take it out of the deck.</li>
|
||||
<li>If there are still cards in the deck then put the next top card of the deck at the bottom of the deck.</li>
|
||||
<li>If there are still unrevealed cards, go back to step 1. Otherwise, stop.</li>
|
||||
</ol>
|
||||
|
||||
<p>Return <em>an ordering of the deck that would reveal the cards in increasing order</em>.</p>
|
||||
|
||||
<p><strong>Note</strong> that the first entry in the answer is considered to be the top of the deck.</p>
|
||||
|
||||
<p> </p>
|
||||
<p><strong class="example">Example 1:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> deck = [17,13,11,2,3,5,7]
|
||||
<strong>Output:</strong> [2,13,3,11,5,17,7]
|
||||
<strong>Explanation:</strong>
|
||||
We get the deck in the order [17,13,11,2,3,5,7] (this order does not matter), and reorder it.
|
||||
After reordering, the deck starts as [2,13,3,11,5,17,7], where 2 is the top of the deck.
|
||||
We reveal 2, and move 13 to the bottom. The deck is now [3,11,5,17,7,13].
|
||||
We reveal 3, and move 11 to the bottom. The deck is now [5,17,7,13,11].
|
||||
We reveal 5, and move 17 to the bottom. The deck is now [7,13,11,17].
|
||||
We reveal 7, and move 13 to the bottom. The deck is now [11,17,13].
|
||||
We reveal 11, and move 17 to the bottom. The deck is now [13,17].
|
||||
We reveal 13, and move 17 to the bottom. The deck is now [17].
|
||||
We reveal 17.
|
||||
Since all the cards revealed are in increasing order, the answer is correct.
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 2:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> deck = [1,1000]
|
||||
<strong>Output:</strong> [1,1000]
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= deck.length <= 1000</code></li>
|
||||
<li><code>1 <= deck[i] <= 10<sup>6</sup></code></li>
|
||||
<li>All the values of <code>deck</code> are <strong>unique</strong>.</li>
|
||||
</ul>
|
||||
@@ -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
|
||||
"""
|
||||
@@ -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't have <strong>two adjacent characters</strong> <code>s[i]</code> and <code>s[i + 1]</code> where:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>0 <= i <= 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> </p>
|
||||
<p><strong class="example">Example 1:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "leEeetcode"
|
||||
<strong>Output:</strong> "leetcode"
|
||||
<strong>Explanation:</strong> In the first step, either you choose i = 1 or i = 2, both will result "leEeetcode" to be reduced to "leetcode".
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 2:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "abBAcC"
|
||||
<strong>Output:</strong> ""
|
||||
<strong>Explanation:</strong> We have many possible scenarios, and all lead to the same answer. For example:
|
||||
"abBAcC" --> "aAcC" --> "cC" --> ""
|
||||
"abBAcC" --> "abBA" --> "aA" --> ""
|
||||
</pre>
|
||||
|
||||
<p><strong class="example">Example 3:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> s = "s"
|
||||
<strong>Output:</strong> "s"
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= s.length <= 100</code></li>
|
||||
<li><code>s</code> contains only lower and upper case English letters.</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
|
||||
@@ -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> </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> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= n <= 5 * 10<sup>4</sup></code></li>
|
||||
<li><code>0 <= relations.length <= min(n * (n - 1) / 2, 5 * 10<sup>4</sup>)</code></li>
|
||||
<li><code>relations[j].length == 2</code></li>
|
||||
<li><code>1 <= prevCourse<sub>j</sub>, nextCourse<sub>j</sub> <= 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 <= time[i] <= 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
|
||||
@@ -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>'N'</code> and <code>'Y'</code>:</p>
|
||||
|
||||
<ul>
|
||||
<li>if the <code>i<sup>th</sup></code> character is <code>'Y'</code>, it means that customers come at the <code>i<sup>th</sup></code> hour</li>
|
||||
<li>whereas <code>'N'</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 <= j <= 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> </p>
|
||||
<p><strong class="example">Example 1:</strong></p>
|
||||
|
||||
<pre>
|
||||
<strong>Input:</strong> customers = "YYNY"
|
||||
<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 = "NNNNN"
|
||||
<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 = "YYYY"
|
||||
<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> </p>
|
||||
<p><strong>Constraints:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><code>1 <= customers.length <= 10<sup>5</sup></code></li>
|
||||
<li><code>customers</code> consists only of characters <code>'Y'</code> and <code>'N'</code>.</li>
|
||||
</ul>
|
||||
Reference in New Issue
Block a user