diff --git a/Average of Levels in Binary Tree - Leetcode 637/Average of Levels in Binary Tree - Leetcode 637.py b/Average of Levels in Binary Tree - Leetcode 637/Average of Levels in Binary Tree - Leetcode 637.py index 91fd272..a8cceec 100644 --- a/Average of Levels in Binary Tree - Leetcode 637/Average of Levels in Binary Tree - Leetcode 637.py +++ b/Average of Levels in Binary Tree - Leetcode 637/Average of Levels in Binary Tree - Leetcode 637.py @@ -12,19 +12,18 @@ def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]: q.append(root) while q: - avg = 0 + summ = 0 n = len(q) for _ in range(n): node = q.popleft() - avg += node.val + summ += node.val if node.left: q.append(node.left) if node.right: q.append(node.right) - avg /= n - avgs.append(avg) + avgs.append(summ / n) return avgs # Time: O(n) diff --git a/Best Time to Buy and Sell Stock - Leetcode 121/Best Time to Buy and Sell Stock - Leetcode 121.py b/Best Time to Buy and Sell Stock - Leetcode 121/Best Time to Buy and Sell Stock - Leetcode 121.py index 6415e77..faf4100 100644 --- a/Best Time to Buy and Sell Stock - Leetcode 121/Best Time to Buy and Sell Stock - Leetcode 121.py +++ b/Best Time to Buy and Sell Stock - Leetcode 121/Best Time to Buy and Sell Stock - Leetcode 121.py @@ -31,3 +31,20 @@ def maxProfit(self, prices: List[int]) -> int: max_profit = profit return max_profit + + +# Optimal Solution for Bootcamp +class Solution: + def maxProfit(self, prices: List[int]) -> int: + # Time: O(n) + # Space: O(1) + min_price = float('inf') + max_profit = 0 + + for price in prices: + profit = price - min_price + + min_price = min(price, min_price) + max_profit = max(profit, max_profit) + + return max_profit diff --git a/Binary Search - Leetcode 704/Binary Search - Leetcode 704.py b/Binary Search - Leetcode 704/Binary Search - Leetcode 704.py index 12a81b5..ad5c032 100644 --- a/Binary Search - Leetcode 704/Binary Search - Leetcode 704.py +++ b/Binary Search - Leetcode 704/Binary Search - Leetcode 704.py @@ -1,3 +1,14 @@ +# Brute Force Solution +class Solution: + def search(self, nums: List[int], target: int) -> int: + n = len(nums) + for i in range(n): + if nums[i] == target: + return i + return -1 + # Time: O(n) + # Space: O(1) + class Solution: def search(self, nums: List[int], target: int) -> int: left = 0 diff --git a/Coin Change - Leetcode 322/Coin Change - Leetcode 322.cpp b/Coin Change - Leetcode 322/Coin Change - Leetcode 322.cpp index 32eb939..0482c5d 100644 --- a/Coin Change - Leetcode 322/Coin Change - Leetcode 322.cpp +++ b/Coin Change - Leetcode 322/Coin Change - Leetcode 322.cpp @@ -2,6 +2,30 @@ #include using namespace std; + +/** + * Brute force approach with simple recursion + */ +class Solution { +public: + int coinChange(vector& coins, int amount) { + if (amount == 0) + return 0; + else if (amount < 0) + return -1; + + int min_cnt = -1; + for (int coin : coins) { + int cnt = coinChange(coins, amount - coin); + if (cnt >= 0) + min_cnt = min_cnt < 0 ? cnt + 1 : min(min_cnt, cnt + 1); + } + return min_cnt; + } +}; + + + class Solution { public: int coinChange(vector& coins, int amount) { diff --git a/Coin Change - Leetcode 322/Coin Change - Leetcode 322.java b/Coin Change - Leetcode 322/Coin Change - Leetcode 322.java index c7d1ee4..59c5ade 100644 --- a/Coin Change - Leetcode 322/Coin Change - Leetcode 322.java +++ b/Coin Change - Leetcode 322/Coin Change - Leetcode 322.java @@ -1,5 +1,28 @@ import java.util.Arrays; + +/** + * Brute force approach with simple recursion + */ +class Solution { + public int coinChange(int[] coins, int amount) { + if (amount == 0) + return 0; + else if (amount < 0) + return -1; + + int min_cnt = -1; + for (int coin : coins) { + int cnt = coinChange(coins, amount - coin); + if (cnt >= 0) + min_cnt = min_cnt < 0 ? cnt + 1 : Math.min(min_cnt, cnt + 1); + } + return min_cnt; + } +} + + + public class Solution { public int coinChange(int[] coins, int amount) { int[] dp = new int[amount + 1]; diff --git a/Coin Change - Leetcode 322/Coin Change - Leetcode 322.js b/Coin Change - Leetcode 322/Coin Change - Leetcode 322.js index 14fd04c..e6aee29 100644 --- a/Coin Change - Leetcode 322/Coin Change - Leetcode 322.js +++ b/Coin Change - Leetcode 322/Coin Change - Leetcode 322.js @@ -1,3 +1,26 @@ +/** + * Brute force approach with simple recursion + * + * @param {number[]} coins + * @param {number} amount + * @return {number} + */ +var coinChange = function(coins, amount) { + if (amount == 0) + return 0; + else if (amount < 0) + return -1; + + let min_cnt = -1; + for (let coin of coins) { + let cnt = coinChange(coins, amount - coin); + if (cnt >= 0) + min_cnt = min_cnt < 0 ? cnt + 1 : Math.min(min_cnt, cnt + 1); + } + return min_cnt; +}; + + /** * @param {number[]} coins * @param {number} amount diff --git a/Coin Change - Leetcode 322/Coin Change - Leetcode 322.py b/Coin Change - Leetcode 322/Coin Change - Leetcode 322.py index c35592d..6d88a3e 100644 --- a/Coin Change - Leetcode 322/Coin Change - Leetcode 322.py +++ b/Coin Change - Leetcode 322/Coin Change - Leetcode 322.py @@ -1,3 +1,22 @@ +class Solution: + def coinChange(self, coins: List[int], amount: int) -> int: + # Brute force with simple recursion + # Time: O(Coins ^ Amount) + # Space: O(Amount) + if amount == 0: + return 0 + elif amount < 0: + return -1 + + min_cnt = -1 + for coin in coins: + cnt = self.coinChange(coins, amount - coin) + if cnt >= 0: + min_cnt = cnt + 1 if min_cnt < 0 else min(min_cnt, cnt + 1) + return min_cnt + + + class Solution: def coinChange(self, coins: List[int], amount: int) -> int: # Top Down DP (Memoization) diff --git a/Contains Duplicate - Leetcode 217/Contains Duplicate - Leetcode 217.py b/Contains Duplicate - Leetcode 217/Contains Duplicate - Leetcode 217.py index c3897ef..2d506f9 100644 --- a/Contains Duplicate - Leetcode 217/Contains Duplicate - Leetcode 217.py +++ b/Contains Duplicate - Leetcode 217/Contains Duplicate - Leetcode 217.py @@ -1,11 +1,38 @@ +# Brute Force Solution +class Solution: + def containsDuplicate(self, nums: List[int]) -> bool: + n = len(nums) + + for i in range(n): + for j in range(n): + if nums[i] == nums[j] and i != j: + return True + return False + # Time Complexity: O(n^2) + # Space Complexity: O(1) + +# Better Brute Force Solution +class Solution: + def containsDuplicate(self, nums: List[int]) -> bool: + n = len(nums) + + for i in range(n): + for j in range(i+1, n): + if nums[i] == nums[j]: + return True + return False + # Time Complexity: O(n^2) + # Space Complexity: O(1) + +# Optimal Solution class Solution: def containsDuplicate(self, nums: list[int]) -> bool: - h = set() + s = set() for num in nums: - if num in h: + if num in s: return True else: - h.add(num) + s.add(num) return False # Time Complexity: O(n) diff --git a/Course Schedule II - Leetcode 210/Course Schedule II - Leetcode 210.py b/Course Schedule II - Leetcode 210/Course Schedule II - Leetcode 210.py index ed8bfab..cd8d244 100644 --- a/Course Schedule II - Leetcode 210/Course Schedule II - Leetcode 210.py +++ b/Course Schedule II - Leetcode 210/Course Schedule II - Leetcode 210.py @@ -7,7 +7,6 @@ def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int UNVISITED, VISITING, VISITED = 0, 1, 2 states = [UNVISITED] * numCourses - def dfs(i): if states[i] == VISITING: diff --git a/Find Minimum in Rotated Sorted Array - Leetcode 153/Find Minimum in Rotated Sorted Array - Leetcode 153.py b/Find Minimum in Rotated Sorted Array - Leetcode 153/Find Minimum in Rotated Sorted Array - Leetcode 153.py index eb84c44..d95496d 100644 --- a/Find Minimum in Rotated Sorted Array - Leetcode 153/Find Minimum in Rotated Sorted Array - Leetcode 153.py +++ b/Find Minimum in Rotated Sorted Array - Leetcode 153/Find Minimum in Rotated Sorted Array - Leetcode 153.py @@ -1,3 +1,16 @@ +# Brute Force Solution +class Solution: + def findMin(self, nums: List[int]) -> int: + minn = float('inf') + for num in nums: + if num < minn: + minn = num + return minn + +# Time: O(n) +# Space: O(1) + +# Optimal Solution class Solution: def findMin(self, nums: List[int]) -> int: n = len(nums) diff --git a/First Bad Version - Leetcode 278/First Bad Version - Leetcode 278.py b/First Bad Version - Leetcode 278/First Bad Version - Leetcode 278.py index a215336..c6b9559 100644 --- a/First Bad Version - Leetcode 278/First Bad Version - Leetcode 278.py +++ b/First Bad Version - Leetcode 278/First Bad Version - Leetcode 278.py @@ -1,6 +1,15 @@ +# Brute Force Solution +class Solution: + def firstBadVersion(self, n: int) -> int: + for version in range(1, n+1): + if isBadVersion(version): + return version + # Time: O(n) + # Space: O(1) + +# Optimal Solution # The isBadVersion API is already defined for you. # def isBadVersion(version: int) -> bool: - class Solution: def firstBadVersion(self, n: int) -> int: L = 1 @@ -13,4 +22,6 @@ def firstBadVersion(self, n: int) -> int: else: L = M + 1 - return L # Time: O(Log n), Space: O(1) + return L + # Time: O(Log n) + # Space: O(1) diff --git a/Group Anagrams - Leetcode 49/Group Anagrams - Leetcode 49.py b/Group Anagrams - Leetcode 49/Group Anagrams - Leetcode 49.py index 28e4bda..06af914 100644 --- a/Group Anagrams - Leetcode 49/Group Anagrams - Leetcode 49.py +++ b/Group Anagrams - Leetcode 49/Group Anagrams - Leetcode 49.py @@ -1,3 +1,17 @@ +# Brute Force Solution +class Solution: + def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + ans = defaultdict(list) + for s in strs: + key = ''.join(sorted(s)) + ans[key].append(s) + + return list(ans.values()) +# Time: O(n * (m log m)) +# Space: O(n * m) +# n is the number of strings, m is the length of largest string + +# Optimal Solution from collections import defaultdict class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: diff --git a/Invert Binary Tree - Leetcode 226/Invert Binary Tree - Leetcode 226.py b/Invert Binary Tree - Leetcode 226/Invert Binary Tree - Leetcode 226.py index a6ea203..1cc0217 100644 --- a/Invert Binary Tree - Leetcode 226/Invert Binary Tree - Leetcode 226.py +++ b/Invert Binary Tree - Leetcode 226/Invert Binary Tree - Leetcode 226.py @@ -1,3 +1,4 @@ +# YouTube Solution class Solution: def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: @@ -13,3 +14,21 @@ def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: # Time Complexity: O(n) # Space Complexity: O(h) { here "h" is the height of the tree } + + +# Solution for Bootcamp +class Solution: + def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + def invert(node): + if not node: + return + + node.left, node.right = node.right, node.left + invert(node.left) + invert(node.right) + + invert(root) + return root + +# Time Complexity: O(n) +# Space Complexity: O(h) { here "h" is the height of the tree } diff --git a/Jewels and Stones - Leetcode 771/Jewels and Stones - Leetcode 771.py b/Jewels and Stones - Leetcode 771/Jewels and Stones - Leetcode 771.py index 1b5c794..2aa2180 100644 --- a/Jewels and Stones - Leetcode 771/Jewels and Stones - Leetcode 771.py +++ b/Jewels and Stones - Leetcode 771/Jewels and Stones - Leetcode 771.py @@ -1,3 +1,17 @@ +# Brute Force Solution +class Solution: + def numJewelsInStones (self, jewels: str, stones: str) -> int: + count = 0 + for stone in stones: + if stone in jewels: + count += 1 + return count + +# Time Complexity: O(n * m) +# Space Complexity: O(1) + + +# Optimal Solution class Solution: def numJewelsInStones (self, jewels: str, stones: str) -> int: # O(n + m) diff --git a/Kth Largest Element in an Array - Leetcode 215/Kth Largest Element in an Array - Leetcode 215.py b/Kth Largest Element in an Array - Leetcode 215/Kth Largest Element in an Array - Leetcode 215.py index 888be45..31354d6 100644 --- a/Kth Largest Element in an Array - Leetcode 215/Kth Largest Element in an Array - Leetcode 215.py +++ b/Kth Largest Element in an Array - Leetcode 215/Kth Largest Element in an Array - Leetcode 215.py @@ -1,3 +1,12 @@ +# Brute Force Solution +class Solution: + def findKthLargest(self, nums: List[int], k: int) -> int: + nums.sort() + return nums[-k] + +# Time: O(n log n) +# Space: O(1) + import heapq class Solution: def findKthLargest(self, nums: List[int], k: int) -> int: @@ -10,7 +19,7 @@ def findKthLargest(self, nums: List[int], k: int) -> int: heapq.heappop(nums) return -heapq.heappop(nums) - # Max Heap of size n + # Max Heap of size n # Time: O(n + k log n) # Space: O(1) diff --git a/Last Stone Weight - Leetcode 1046/Last Stone Weight - Leetcode 1046.py b/Last Stone Weight - Leetcode 1046/Last Stone Weight - Leetcode 1046.py index 7459bbe..f0966b5 100644 --- a/Last Stone Weight - Leetcode 1046/Last Stone Weight - Leetcode 1046.py +++ b/Last Stone Weight - Leetcode 1046/Last Stone Weight - Leetcode 1046.py @@ -1,3 +1,22 @@ +# Brute Force Solution +class Solution: + def lastStoneWeight(self, stones: List[int]) -> int: + + def remove_largest(): + index_of_largest = stones.index(max(stones)) + return stones.pop(index_of_largest) + + while len(stones) > 1: + stone_1 = remove_largest() + stone_2 = remove_largest() + if stone_1 != stone_2: + stones.append(stone_1 - stone_2) + + return stones[0] if stones else 0 +# Time: O(n^2) +# Space: O(1) + +# Optimal Solution class Solution: def lastStoneWeight(self, stones: List[int]) -> int: for i in range(len(stones)): diff --git a/Linked List Cycle - Leetcode 141/Linked List Cycle - Leetcode 141.py b/Linked List Cycle - Leetcode 141/Linked List Cycle - Leetcode 141.py index da86af6..d0b3fd7 100644 --- a/Linked List Cycle - Leetcode 141/Linked List Cycle - Leetcode 141.py +++ b/Linked List Cycle - Leetcode 141/Linked List Cycle - Leetcode 141.py @@ -1,8 +1,6 @@ class Solution: def hasCycle(self, head: Optional[ListNode]) -> bool: - dummy = ListNode() - dummy.next = head - slow = fast = dummy + slow = fast = head while fast and fast.next: fast = fast.next.next diff --git a/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.cpp b/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.cpp index 250c098..1932b34 100644 --- a/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.cpp +++ b/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.cpp @@ -2,6 +2,30 @@ #include using namespace std; + + +class Solution { +public: + int lengthOfLongestSubstring(const string s) { + + int longest = 0; + + for (auto i = 0; i < s.size(); ++i) { + for (auto substr_len = 1; i + substr_len <= s.size(); ++substr_len) { + unordered_set seen{s.cbegin() + i, s.cbegin() + i + substr_len}; + if (seen.size() == substr_len) + longest = max(longest, substr_len); + } + } + + return longest; + } +}; +// Time Complexity: O(n^3) +// Space Complexity: O(n) + + + class Solution { public: int lengthOfLongestSubstring(string s) { diff --git a/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.java b/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.java index 510219a..1fdaaac 100644 --- a/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.java +++ b/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.java @@ -1,5 +1,31 @@ import java.util.HashSet; + +// brute force +// Time Complexity: O(n^3) +// Space Complexity: O(n) +public class Solution { + public int lengthOfLongestSubstring(String s) { + int longest = 0; + int n = s.length(); + for (int i = 0; i < n; i++) { + for (int substr_len = 1; i + substr_len <= n; ++substr_len) { + HashSet seen = new HashSet<>(); + for (int j = i; j < i + substr_len; ++j) + seen.add(s.charAt(j)); + + if (seen.size() == substr_len) + longest = Math.max(longest, substr_len); + } + } + + return longest; + } +} + + + + public class Solution { public int lengthOfLongestSubstring(String s) { HashSet set = new HashSet<>(); diff --git a/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.js b/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.js index 807da86..499fccf 100644 --- a/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.js +++ b/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.js @@ -1,3 +1,26 @@ +// brute force +// Time Complexity: O(n^3) +// Space Complexity: O(n) +var lengthOfLongestSubstring = function(s) { + + let longest = 0; + let n = s.length; + for (let i = 0; i < n; ++i) { + for (let substr_len = 1; i + substr_len <= n; ++substr_len) { + var seen = new Set(); + for (let j = i; j < i + substr_len; ++j) { + seen.add(s[j]); + } + if (seen.size == substr_len) { + longest = Math.max(longest, substr_len); + } + } + } + + return longest; +}; + + var lengthOfLongestSubstring = function(s) { const set = new Set(); let l = 0, longest = 0; diff --git a/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.py b/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.py index ee06243..52010ff 100644 --- a/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.py +++ b/Longest Substring Without Repeating Characters - Leetcode 3/Longest Substring Without Repeating Characters - Leetcode 3.py @@ -1,3 +1,17 @@ +# Brute Force +def length_of_longest_substring(s: str) -> int: + max_length = 0 + + for i in range(len(s)): + for j in range(i, len(s)): + if s[j] in s[i:j]: # Check if the character already appeared in the substring + break + max_length = max(max_length, j - i + 1) + + return max_length + # Time: O(n^3) + # Space: O(n) + class Solution: def lengthOfLongestSubstring(self, s: str) -> int: l = 0 diff --git a/Max Consecutive Ones III - Leetcode 1004/brute force.cpp b/Max Consecutive Ones III - Leetcode 1004/brute force.cpp new file mode 100644 index 0000000..3a8c72c --- /dev/null +++ b/Max Consecutive Ones III - Leetcode 1004/brute force.cpp @@ -0,0 +1,29 @@ +class Solution { +public: + int longestOnes(vector& nums, int k) { + int n = nums.size(); + int maxLen = 0; + + // Iterate over all starting points of subarrays + for (int i = 0; i < n; ++i) { + + // Check each subarray starting from `i` + for (int j = i; j < n; ++j) { + int zeroCount = 0; + for (int c = i; c <= j; ++c) { + if (nums[c] == 0) + zeroCount++; + } + + // If the number of zeroes exceeds k, + // update the maximum length + if (zeroCount <= k) { + maxLen = max(maxLen, j - i + 1); + } + + } + } + + return maxLen; + } +}; diff --git a/Max Consecutive Ones III - Leetcode 1004/brute force.java b/Max Consecutive Ones III - Leetcode 1004/brute force.java new file mode 100644 index 0000000..1df7076 --- /dev/null +++ b/Max Consecutive Ones III - Leetcode 1004/brute force.java @@ -0,0 +1,27 @@ +public class Solution { + public int longestOnes(int[] nums, int k) { + int maxLength = 0; + + // Iterate over all starting points + for (int i = 0; i < nums.length; i++) { + + // Iterate over all possible subarrays starting from i + for (int j = i; j < nums.length; j++) { + + int zeroCount = 0; + for (int c = i; c <= j; ++c) { + if (nums[c] == 0) + ++zeroCount; + } + + // Update maxLength if this subarray is valid + if (zeroCount <= k) { + maxLength = Math.max(maxLength, j - i + 1); + } + + } + } + + return maxLength; + } +} diff --git a/Max Consecutive Ones III - Leetcode 1004/brute force.js b/Max Consecutive Ones III - Leetcode 1004/brute force.js new file mode 100644 index 0000000..cd743b2 --- /dev/null +++ b/Max Consecutive Ones III - Leetcode 1004/brute force.js @@ -0,0 +1,30 @@ +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var longestOnes = function(nums, k) { + let maxLength = 0; + + // Iterate over all starting points + for (let i = 0; i < nums.length; i++) { + + // Iterate over all possible subarrays starting from i + for (let j = i; j < nums.length; j++) { + let zeroCount = 0; + for (let c = i; c <= j; ++c) { + if (nums[c] == 0) + ++zeroCount; + } + + // If the number of zeroes exceeds k, + // update the maximum length + if (zeroCount <= k) { + maxLength = Math.max(maxLength, j - i + 1); + } + + } + } + + return maxLength; +}; diff --git a/Max Consecutive Ones III - Leetcode 1004/brute force.py b/Max Consecutive Ones III - Leetcode 1004/brute force.py new file mode 100644 index 0000000..be6b73d --- /dev/null +++ b/Max Consecutive Ones III - Leetcode 1004/brute force.py @@ -0,0 +1,19 @@ +class Solution(object): + def longestOnes(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: int + """ + longest_ones = 0 + + # Iterate over all starting points + for i in range(len(nums)): + + # Iterate over all possible subarrays starting from i + for j in range(i + 1, len(nums) + 1): + window_len = j - i + num_zeros = nums[i:j].count(0) # O(k) operation + if num_zeros <= k: + longest_ones = max(longest_ones, window_len) + return longest_ones diff --git a/Maximum Average Subarray I - Leetcode 643/brute force.cpp b/Maximum Average Subarray I - Leetcode 643/brute force.cpp new file mode 100644 index 0000000..e399fe5 --- /dev/null +++ b/Maximum Average Subarray I - Leetcode 643/brute force.cpp @@ -0,0 +1,22 @@ +class Solution { +public: + double findMaxAverage(const vector& nums, int k) { + double max_avg = 0; + + // setting max_avg to any constant numeric value + // here is incorrect!!! + // So initialize it with some values from the input + for (int i = 0; i < k; ++i) + max_avg += nums[i]; + max_avg /= k; + + for (int i = 0; i <= nums.size() - k; ++i) { + double avg = 0; + for (int j = i; j < i + k; ++j) + avg += nums[j]; + avg /= k; + max_avg = max(max_avg, avg); + } + return max_avg; + } +}; diff --git a/Maximum Average Subarray I - Leetcode 643/brute force.java b/Maximum Average Subarray I - Leetcode 643/brute force.java new file mode 100644 index 0000000..6dfd656 --- /dev/null +++ b/Maximum Average Subarray I - Leetcode 643/brute force.java @@ -0,0 +1,22 @@ +class Solution { + public double findMaxAverage(int[] nums, int k) { + double max_avg = 0; + + // setting max_avg to any constant numeric value + // here is incorrect!!! + // So initialize it with some values from the input + for (int i = 0; i < k; ++i) + max_avg += nums[i]; + max_avg /= k; + + for (int i = 0; i <= nums.length - k; ++i) { + double avg = 0; + for (int j = i; j < i + k; ++j) + avg += nums[j]; + avg /= k; + max_avg = Math.max(max_avg, avg); + } + return max_avg; + + } +} diff --git a/Maximum Average Subarray I - Leetcode 643/brute force.js b/Maximum Average Subarray I - Leetcode 643/brute force.js new file mode 100644 index 0000000..07469e7 --- /dev/null +++ b/Maximum Average Subarray I - Leetcode 643/brute force.js @@ -0,0 +1,22 @@ +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var findMaxAverage = function(nums, k) { + const avg = (vals, start, len) => { + let sum = 0; + for (let i = start; i < start + len; i++) { + sum += vals[i]; + } + return sum / len; + }; + + // Calculate initial maximum average + let maxAvg = avg(nums, 0, k); + for (let i = 0; i <= nums.length - k; i++) { + maxAvg = Math.max(maxAvg, avg(nums, i, k)); + } + + return maxAvg; +}; diff --git a/Maximum Average Subarray I - Leetcode 643/brute force.py b/Maximum Average Subarray I - Leetcode 643/brute force.py new file mode 100644 index 0000000..1de4fbf --- /dev/null +++ b/Maximum Average Subarray I - Leetcode 643/brute force.py @@ -0,0 +1,20 @@ +class Solution(object): + def findMaxAverage(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: float + """ + + def avg(vals): + return sum(vals) / float(len(vals)) + + # Note, setting max_avg to any constant numeric value + # here is incorrect!!! + # Say 0, if nums = [-1, -2, -3, -4], k = 2, + # the output would be incorrect + max_avg = avg(nums[:k]) + for i in range(len(nums) - k + 1): + max_avg = max(max_avg, avg(nums[i:i+k])) # avg is O(k) + return max_avg + diff --git a/Maximum Depth of Binary Tree - Leetcode 104/Maximum Depth of Binary Tree - Leetcode 104.py b/Maximum Depth of Binary Tree - Leetcode 104/Maximum Depth of Binary Tree - Leetcode 104.py index 061c10f..9cf4d38 100644 --- a/Maximum Depth of Binary Tree - Leetcode 104/Maximum Depth of Binary Tree - Leetcode 104.py +++ b/Maximum Depth of Binary Tree - Leetcode 104/Maximum Depth of Binary Tree - Leetcode 104.py @@ -1,3 +1,4 @@ +# DFS class Solution: def maxDepth(self, root: Optional[TreeNode]) -> int: if not root: @@ -10,3 +11,28 @@ def maxDepth(self, root: Optional[TreeNode]) -> int: # Time Complexity: O(n) # Space Complexity: O(h) { here "h" is the height of the binary tree } + +# BFS +class Solution: + def maxDepth(self, root): + if not root: + return 0 # Height of an empty tree is 0 + + queue = deque([root]) + height = 0 + + while queue: + level_size = len(queue) # Number of nodes at the current level + + for _ in range(level_size): + node = queue.popleft() + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + + height += 1 # Increment height at each level + + return height + # Time Complexity: O(n) + # Space Complexity: O(n) diff --git a/Merge Intervals - Leetcode 56/Merge Intervals - Leetcode 56.py b/Merge Intervals - Leetcode 56/Merge Intervals - Leetcode 56.py index f98cfb7..b94f8ac 100644 --- a/Merge Intervals - Leetcode 56/Merge Intervals - Leetcode 56.py +++ b/Merge Intervals - Leetcode 56/Merge Intervals - Leetcode 56.py @@ -12,3 +12,23 @@ def merge(self, intervals: List[List[int]]) -> List[List[int]]: return merged # Time: O(n log n) # Space: O(n) + + +class Solution: + def merge(self, intervals: List[List[int]]) -> List[List[int]]: + intervals.sort(key=lambda x: x[0]) # Sort by start time + i = 0 # Index to track merged intervals + n = len(intervals) + + for j in range(1, n): + # Check if the current interval overlaps with the previous one + if intervals[i][1] >= intervals[j][0]: + intervals[i][1] = max(intervals[i][1], intervals[j][1]) # Merge + else: + i += 1 + intervals[i] = intervals[j] # Move next non-overlapping interval + + return intervals[:i+1] # Return the relevant merged portion + + # Time: O(n log n) + # Space: O(1) diff --git a/Merge Strings Alternately - Leetcode 1768/Merge Strings Alternately - Leetcode 1768.py b/Merge Strings Alternately - Leetcode 1768/Merge Strings Alternately - Leetcode 1768.py index ffd2397..ac9a73d 100644 --- a/Merge Strings Alternately - Leetcode 1768/Merge Strings Alternately - Leetcode 1768.py +++ b/Merge Strings Alternately - Leetcode 1768/Merge Strings Alternately - Leetcode 1768.py @@ -1,3 +1,38 @@ +# Brute Force Solution +class Solution: + def mergeAlternately(self, word1: str, word2: str) -> str: + characters = "" + cur_word = 1 + a, b = 0, 0 + + while a < len(word1) and b < len(word2): + if cur_word == 1: + characters += word1[a] + a += 1 + cur_word = 2 + else: + characters += word2[b] + b += 1 + cur_word = 1 + + while a < len(word1): + characters += word1[a] + a += 1 + + while b < len(word2): + characters += word2[b] + b += 1 + + return characters + # Let A be the length of Word1 + # Let B be the length of Word2 + # Let T = A + B + + # Time: O(T^2) + # Space: O(T) + + +# Optimal Solution class Solution: def mergeAlternately(self, word1: str, word2: str) -> str: A, B = len(word1), len(word2) @@ -24,5 +59,9 @@ def mergeAlternately(self, word1: str, word2: str) -> str: b += 1 return ''.join(s) - # Time: O(A + B) - A is Length of word1, B is Length of word2 - # Space: O(A + B) - A is Length of word1, B is Length of word2 + # Let A be the length of Word1 + # Let B be the length of Word2 + # Let T = A + B + + # Time: O(T) + # Space: O(T) diff --git a/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.cpp b/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.cpp new file mode 100644 index 0000000..accc47c --- /dev/null +++ b/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.cpp @@ -0,0 +1,30 @@ +#include +#include + +using namespace std; + +class Solution { +public: + vector> levelOrder(Node* root) { + vector> output; + if (!root) return output; + + queue q; + q.push(root); + + while (!q.empty()) { + int n = q.size(); + vector level; + for (int i = 0; i < n; i++) { + Node* node = q.front(); + q.pop(); + level.push_back(node->val); + for (Node* child : node->children) { + q.push(child); + } + } + output.push_back(level); + } + return output; + } +}; diff --git a/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.java b/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.java new file mode 100644 index 0000000..2759a8f --- /dev/null +++ b/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.java @@ -0,0 +1,26 @@ +import java.util.*; + + +class Solution { + public List> levelOrder(Node root) { + List> output = new ArrayList<>(); + if (root == null) return output; + + Queue q = new LinkedList<>(); + q.add(root); + + while (!q.isEmpty()) { + int n = q.size(); + List level = new ArrayList<>(); + for (int i = 0; i < n; i++) { + Node node = q.poll(); + level.add(node.val); + if (node.children != null) { + q.addAll(node.children); + } + } + output.add(level); + } + return output; + } +} diff --git a/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.js b/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.js new file mode 100644 index 0000000..5b8adf9 --- /dev/null +++ b/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.js @@ -0,0 +1,20 @@ +var levelOrder = function(root) { + if (!root) return []; + + let output = []; + let q = [root]; + + while (q.length > 0) { + let n = q.length; + let level = []; + for (let i = 0; i < n; i++) { + let node = q.shift(); + level.push(node.val); + if (node.children) { + q.push(...node.children); + } + } + output.push(level); + } + return output; +}; diff --git a/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.py b/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.py new file mode 100644 index 0000000..34fa64d --- /dev/null +++ b/N-ary Tree Level Order Traversal - Leetcode 429/N-ary Tree Level Order Traversal - Leetcode 429.py @@ -0,0 +1,31 @@ +""" +# Definition for a Node. +class Node: + def __init__(self, val: Optional[int] = None, children: Optional[List['Node']] = None): + self.val = val + self.children = children +""" + +class Solution: + def levelOrder(self, root: 'Node') -> List[List[int]]: + if not root: + return [] + output = [] + q = deque() + q.append(root) + + while q: + n = len(q) + level = [] + for _ in range(n): + node = q.popleft() + level.append(node.val) + for child in node.children: + q.append(child) + output.append(level) + + return output + + # Time: O(n) + # Space: O(n) + # n is number of nodes in the tree \ No newline at end of file diff --git a/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.cpp b/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.cpp new file mode 100644 index 0000000..accc47c --- /dev/null +++ b/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.cpp @@ -0,0 +1,30 @@ +#include +#include + +using namespace std; + +class Solution { +public: + vector> levelOrder(Node* root) { + vector> output; + if (!root) return output; + + queue q; + q.push(root); + + while (!q.empty()) { + int n = q.size(); + vector level; + for (int i = 0; i < n; i++) { + Node* node = q.front(); + q.pop(); + level.push_back(node->val); + for (Node* child : node->children) { + q.push(child); + } + } + output.push_back(level); + } + return output; + } +}; diff --git a/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.java b/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.java new file mode 100644 index 0000000..ac21f6d --- /dev/null +++ b/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.java @@ -0,0 +1,18 @@ +import java.util.*; + + +class Solution { + public List preorder(Node root) { + List output = new ArrayList<>(); + if (root == null) return output; + dfs(root, output); + return output; + } + + private void dfs(Node node, List output) { + output.add(node.val); + for (Node child : node.children) { + dfs(child, output); + } + } +} diff --git a/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.js b/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.js new file mode 100644 index 0000000..b3ae283 --- /dev/null +++ b/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.js @@ -0,0 +1,15 @@ +var preorder = function(root) { + if (!root) return []; + + let output = []; + + function dfs(node) { + output.push(node.val); + for (let child of node.children) { + dfs(child); + } + } + + dfs(root); + return output; +}; diff --git a/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.py b/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.py new file mode 100644 index 0000000..896cfa2 --- /dev/null +++ b/N-ary Tree Preorder Traversal - Leetcode 589/N-ary Tree Preorder Traversal - Leetcode 429.py @@ -0,0 +1,25 @@ +""" +# Definition for a Node. +class Node: + def __init__(self, val: Optional[int] = None, children: Optional[List['Node']] = None): + self.val = val + self.children = children +""" + +class Solution: + def preorder(self, root: 'Node') -> List[int]: + if not root: + return [] + + output = [] + def dfs(node): + output.append(node.val) + for child in node.children: + dfs(child) + + dfs(root) + return output + + # Time: O(n) + # Space: O(n) + # n is number of nodes in the tree \ No newline at end of file diff --git a/Product of Array Except Self - Leetcode 238/Product of Array Except Self - Leetcode 238.py b/Product of Array Except Self - Leetcode 238/Product of Array Except Self - Leetcode 238.py index a0232d4..63c25b1 100644 --- a/Product of Array Except Self - Leetcode 238/Product of Array Except Self - Leetcode 238.py +++ b/Product of Array Except Self - Leetcode 238/Product of Array Except Self - Leetcode 238.py @@ -1,3 +1,22 @@ +# Brute Force Solution +class Solution: + def productExceptSelf(self, nums: List[int]) -> List[int]: + n = len(nums) + ans = [0] * n + + for i in range(n): + prod = 1 + for j in range(n): + if i != j: + prod *= nums[j] + ans[i] = prod + + return ans + # Time: O(n^2) + # Space: O(n) + + +# Optimal Solution class Solution: def productExceptSelf(self, nums: List[int]) -> List[int]: l_mult = 1 @@ -17,3 +36,33 @@ def productExceptSelf(self, nums: List[int]) -> List[int]: # Time Complexity: O(n) # Space Complexity: O(n) + + +# Optimal Solution for Bootcamp +class Solution: + def productExceptSelf(self, nums: List[int]) -> List[int]: + n = len(nums) + answer = [0] * n + + L = 1 + left_product = [0] * n + + for i in range(n): + left_product[i] = L + L *= nums[i] + + + R = 1 + right_product = [0] * n + + for i in range(n-1, -1, -1): + right_product[i] = R + R *= nums[i] + + + for i in range(n): + answer[i] = left_product[i] * right_product[i] + + return answer +# Time Complexity: O(n) +# Space Complexity: O(n) diff --git a/Ransom Note - Leetcode 383/Ransom Note - Leetcode 383.py b/Ransom Note - Leetcode 383/Ransom Note - Leetcode 383.py index fba5a04..3f5de88 100644 --- a/Ransom Note - Leetcode 383/Ransom Note - Leetcode 383.py +++ b/Ransom Note - Leetcode 383/Ransom Note - Leetcode 383.py @@ -1,3 +1,18 @@ +# Brute Force Solution +class Solution: + def canConstruct(self, ransomNote: str, magazine: str) -> bool: + for letter in ransomNote: + if letter in magazine: + position = magazine.index(letter) + magazine = magazine[:position] + magazine[position+1:] + else: + return False + + return True +# Time: O(R * M) +# Space: O(1) + +# Optimal Solution class Solution: def canConstruct(self, ransomNote: str, magazine: str) -> bool: hashmap = Counter(magazine) # TC for Counter is O(n) @@ -9,5 +24,5 @@ def canConstruct(self, ransomNote: str, magazine: str) -> bool: return False return True -# Time Complexity: O(m + n) -> m = len(ransomNote), n = len(magazine) -# Space Complexity: O(n) -> we're using a hashmap \ No newline at end of file +# Time Complexity: O(R + M) -> R = len(ransomNote), M = len(magazine) +# Space Complexity: O(M) -> we're using a hashmap diff --git a/Reverse String - Leetcode 344/Reverse String - Leetcode 344.py b/Reverse String - Leetcode 344/Reverse String - Leetcode 344.py index 48cd942..0f947f0 100644 --- a/Reverse String - Leetcode 344/Reverse String - Leetcode 344.py +++ b/Reverse String - Leetcode 344/Reverse String - Leetcode 344.py @@ -1,3 +1,21 @@ +# Brute Force Solution +class Solution: + def reverseString(self, s: List[str]) -> None: + """ + Do not return anything, modify s in-place instead. + """ + n = len(s) + T = [] + for i in range(n-1, -1, -1): + T.append(s[i]) + + for i in range(n): + s[i] = T[i] + + # Time: O(n) + # Space: O(n) + +# Two Pointers (Optimal) Solution class Solution: def reverseString(self, s: List[str]) -> None: """ diff --git a/Rotting Oranges - Leetcode 994/Rotting Oranges - Leetcode 994.py b/Rotting Oranges - Leetcode 994/Rotting Oranges - Leetcode 994.py index 32f3ce0..c14eb3f 100644 --- a/Rotting Oranges - Leetcode 994/Rotting Oranges - Leetcode 994.py +++ b/Rotting Oranges - Leetcode 994/Rotting Oranges - Leetcode 994.py @@ -1,3 +1,40 @@ +# Code for Bootcamp +class Solution: + from collections import deque + + def orangesRotting(self, grid): + # Initialize variables + Minute = 0 + Q = deque() + FreshCount = 0 + M, N = len(grid), len(grid[0]) + + # Populate queue with initial rotten oranges and count fresh oranges + for i in range(M): + for j in range(N): + if grid[i][j] == 2: + Q.append((i, j)) + elif grid[i][j] == 1: + FreshCount += 1 + + # Perform BFS + while Q and FreshCount > 0: + NumRotting = len(Q) + for _ in range(NumRotting): + i, j = Q.popleft() + for r, c in [(i, j + 1), (i + 1, j), (i, j - 1), (i - 1, j)]: + if 0 <= r < M and 0 <= c < N and grid[r][c] == 1: + grid[r][c] = 2 + FreshCount -= 1 + Q.append((r, c)) + Minute += 1 # Increment minute after processing all rotten oranges in this round + + # Return the time taken or -1 if fresh oranges remain + return Minute if FreshCount == 0 else -1 + + + +# Code for YouTube Video from collections import deque class Solution: def orangesRotting(self, grid: List[List[int]]) -> int: diff --git a/Same Binary Tree - Leetcode 100/Same Binary Tree - Leetcode 100.py b/Same Binary Tree - Leetcode 100/Same Binary Tree - Leetcode 100.py index 920eff1..da4e7fc 100644 --- a/Same Binary Tree - Leetcode 100/Same Binary Tree - Leetcode 100.py +++ b/Same Binary Tree - Leetcode 100/Same Binary Tree - Leetcode 100.py @@ -1,19 +1,26 @@ +# 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 isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool: + # 1: Both Null + if not p and not q: + return True + + # 2: One is Null + if (p and not q) or (q and not p): + return False + + # 3. Values Mismatch + if p.val != q.val: + return False + + return self.isSameTree(p.left, q.left) and \ + self.isSameTree(p.right, q.right) - def balanced(p, q): - if not p and not q: - return True - - if (p and not q) or (q and not p): - return False - - if p.val != q.val: - return False - - return balanced(p.left, q.left) and balanced(p.right, q.right) - - return balanced(p, q) - -# Time Complexity: O(n) -# Space Complexity: O(h) { here "h" is the height of the tree } +# Time Complexity: O(n + m) +# Space Complexity: O(n + m) +# m is number of nodes in p, n is number of nodes in Q. diff --git a/Search a 2D Matrix - Leetcode 74/Search a 2D Matrix - Leetcode 74.py b/Search a 2D Matrix - Leetcode 74/Search a 2D Matrix - Leetcode 74.py index c45100a..18a6f3d 100644 --- a/Search a 2D Matrix - Leetcode 74/Search a 2D Matrix - Leetcode 74.py +++ b/Search a 2D Matrix - Leetcode 74/Search a 2D Matrix - Leetcode 74.py @@ -1,3 +1,28 @@ +# Brute Force Solution +class Solution: + def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: + for row in matrix: + if target in row: + return True + + return False +# Time: O(m * n) +# Space: O(1) + +# Brute Force Solution With (i, j) indices +class Solution: + def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: + m, n = len(matrix), len(matrix[0]) + for i in range(m): + for j in range(n): + if target == matrix[i][j]: + return True + + return False +# Time: O(m * n) +# Space: O(1) + +# Optimal Solution class Solution: def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: m = len(matrix) @@ -7,17 +32,17 @@ def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: r = t - 1 while l <= r: - m = (l + r) // 2 - i = m // n - j = m % n - mid_num = matrix[i][j] + mid = (l + r) // 2 + mid_i = mid // n + mid_j = mid % n + mid_num = matrix[mid_i][mid_j] if target == mid_num: return True elif target < mid_num: - r = m - 1 + r = mid - 1 else: - l = m + 1 + l = mid + 1 return False diff --git a/Squares of a Sorted Array - Leetcode 977/Squares of a Sorted Array - Leetcode 977.py b/Squares of a Sorted Array - Leetcode 977/Squares of a Sorted Array - Leetcode 977.py index 1174376..2ed626c 100644 --- a/Squares of a Sorted Array - Leetcode 977/Squares of a Sorted Array - Leetcode 977.py +++ b/Squares of a Sorted Array - Leetcode 977/Squares of a Sorted Array - Leetcode 977.py @@ -1,3 +1,44 @@ +# Brute Force Solution +class Solution: + def sortedSquares(self, nums: List[int]) -> List[int]: + n = len(nums) + for i in range(n): + nums[i] = nums[i] ** 2 + + nums.sort() + + return nums + +# Time: O(n log n) +# Space: O(1) + +# Optimal Solution for Bootcamp +class Solution: + def sortedSquares(self, nums: List[int]) -> List[int]: + n = len(nums) + L, R = 0, n-1 + result = [0] * n + + for i in range(n): + nums[i] = nums[i] ** 2 + + j = n-1 + while L <= R: + if nums[L] > nums[R]: + result[j] = nums[L] + L += 1 + else: + result[j] = nums[R] + R -= 1 + + j -= 1 + + return result +# Time: O(n) +# Space: O(n) + + +# Optimal Solution in YT Video class Solution: def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 @@ -17,4 +58,4 @@ def sortedSquares(self, nums: List[int]) -> List[int]: return result # Time Complexity: O(n) -# Space Complexity: O(1) +# Space Complexity: O(n) diff --git a/Subsets - Leetcode 78/Subsets - Leetcode 78.py b/Subsets - Leetcode 78/Subsets - Leetcode 78.py index 0739377..0c77de4 100644 --- a/Subsets - Leetcode 78/Subsets - Leetcode 78.py +++ b/Subsets - Leetcode 78/Subsets - Leetcode 78.py @@ -1,11 +1,11 @@ class Solution: def subsets(self, nums: List[int]) -> List[List[int]]: n = len(nums) - res, sol = [], [] + ans, sol = [], [] def backtrack(i): if i == n: - res.append(sol[:]) + ans.append(sol[:]) return # Don't pick nums[i] @@ -17,7 +17,7 @@ def backtrack(i): sol.pop() backtrack(0) - return res + return ans # Time Complexity: O(2^n) # Space Complexity: O(n) diff --git a/Top K Frequent Elements - Leetcode 347/Top K Frequent Elements - Leetcode 347.py b/Top K Frequent Elements - Leetcode 347/Top K Frequent Elements - Leetcode 347.py index f399730..a89a7e6 100644 --- a/Top K Frequent Elements - Leetcode 347/Top K Frequent Elements - Leetcode 347.py +++ b/Top K Frequent Elements - Leetcode 347/Top K Frequent Elements - Leetcode 347.py @@ -16,6 +16,22 @@ def topKFrequent(self, nums: List[int], k: int) -> List[int]: # Time: O(n log k), Space: O(k) +import heapq +from collections import Counter + +def top_k_frequent(nums, k): + # Step 1: Count frequency + freq_map = Counter(nums) + + # Step 2: Use max heap (invert frequency to simulate max heap) + max_heap = [(-freq, num) for num, freq in freq_map.items()] + heapq.heapify(max_heap) # Convert list into a heap in O(n) + + # Step 3: Extract k most frequent elements + result = [heapq.heappop(max_heap)[1] for _ in range(k)] + return result + # Max Heap + # Buckets from collections import Counter class Solution: diff --git a/Two Sum - Leetcode 1/Two Sum - Leetcode 1.py b/Two Sum - Leetcode 1/Two Sum - Leetcode 1.py index 620d24a..7b51c94 100644 --- a/Two Sum - Leetcode 1/Two Sum - Leetcode 1.py +++ b/Two Sum - Leetcode 1/Two Sum - Leetcode 1.py @@ -1,3 +1,26 @@ +# Brute Force Solution +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + n = len(nums) + for i in range(n): + for j in range(n): + if nums[i] + nums[j] == target and i != j: + return (i, j) + # Time: O(n^2) + # Space: O(1) + +# Better Brute Force Solution +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + n = len(nums) + for i in range(n): + for j in range(i+1, n): + if nums[i] + nums[j] == target: + return (i, j) + # Time: O(n^2) + # Space: O(1) + +# 2-Pass Optimal Solution class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: h = {} @@ -9,6 +32,19 @@ def twoSum(self, nums: List[int], target: int) -> List[int]: if y in h and h[y] != i: return [i, h[y]] +# Time Complexity: O(n) +# Space Complexity: O(n) +# One-Pass Optimal Solution (For Bootcamp) +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + h = {} + n = len(nums) + for i, x in enumerate(nums): + y = target - x + if y in h: + return [i, h[y]] + else: + h[x] = i # Time Complexity: O(n) # Space Complexity: O(n) diff --git a/Valid Anagram - Leetcode 242/Valid Anagram - Leetcode 242.py b/Valid Anagram - Leetcode 242/Valid Anagram - Leetcode 242.py index f50edef..3d85457 100644 --- a/Valid Anagram - Leetcode 242/Valid Anagram - Leetcode 242.py +++ b/Valid Anagram - Leetcode 242/Valid Anagram - Leetcode 242.py @@ -9,5 +9,6 @@ def isAnagram(self, s: str, t: str) -> bool: return s_dict == t_dict +# Let n be the length of the longest word # Time complexity: O(n) # Space complexity: O(n) diff --git a/Validate Binary Search Tree - Leetcode 98/Validate Binary Search Tree - Leetcode 98.py b/Validate Binary Search Tree - Leetcode 98/Validate Binary Search Tree - Leetcode 98.py index f91cc2a..d8a9a1f 100644 --- a/Validate Binary Search Tree - Leetcode 98/Validate Binary Search Tree - Leetcode 98.py +++ b/Validate Binary Search Tree - Leetcode 98/Validate Binary Search Tree - Leetcode 98.py @@ -13,3 +13,25 @@ def is_valid(node, minn, maxx): # Time Complexity: O(n) # Space Complexity: O(h) { here "h" is height of tree } + + +# Bootcamp solution +class Solution: + def isValidBST(self, root: Optional[TreeNode]) -> bool: + stk = [(root, float('-inf'), float('inf'))] + + while stk: + node, minn, maxx = stk.pop() + + if node.val <= minn or node.val >= maxx: + return False + else: + if node.left: + stk.append((node.left, minn, node.val)) + + if node.right: + stk.append((node.right, node.val, maxx)) + + return True +# Time Complexity: O(n) +# Space Complexity: O(h) { here "h" is height of tree }