diff --git a/best-time-to-buy-and-sell-stock/JoyJaewon.py b/best-time-to-buy-and-sell-stock/JoyJaewon.py new file mode 100644 index 000000000..33f5258de --- /dev/null +++ b/best-time-to-buy-and-sell-stock/JoyJaewon.py @@ -0,0 +1,34 @@ +''' +Brainstorm +- Brute force: double for-loop O(N^2) +- Efficient: single pass O(N) + +Plan +1. Initialize the variables +2. Iterate through each price + 2-1. Update the min price + 2-2. Calculate and update max profit +3. Return the max profit +''' + + +def maxProfit(prices): + min_price = float('inf') + max_profit = 0 + for price in prices: + if price < min_price: + min_price = price + elif price - min_price > max_profit: + max_profit = price - min_price + return max_profit + +#TC: O(N), SC: O(1) + +# Normal Case +print(maxProfit([7, 1, 5, 3, 6, 4]) == 5) +print(maxProfit([7, 6, 4, 3, 1]) == 0) + +# Edge Case +print(maxProfit([]) == 0) +print(maxProfit([1]) == 0) + diff --git a/contains-duplicate/JoyJaewon.py b/contains-duplicate/JoyJaewon.py new file mode 100644 index 000000000..cae5bc2af --- /dev/null +++ b/contains-duplicate/JoyJaewon.py @@ -0,0 +1,31 @@ +''' +Brainstrom +- brute force: double for-loop (O^2) +- efficient approach: use set O(N) + +Plan +1. Initialize the set +2. Iterate over the array + 2-1. For each element, check if it's in the set. If it is, return True + 2-2. If not, add the num to the set +3. Return False since no duplicates are found +''' + +def containsDuplicate(nums): + num_set=set() + for num in nums: + if num in num_set: + return True + num_set.add(num) + return False + +#TC: O(N), SC: O(N) + +#Normal case +print(containsDuplicate([1, 2, 3, 1]) == True) +print(containsDuplicate([1, 2, 3, 4]) == False) + +#Edge case +print(containsDuplicate([1]) == False) +print(containsDuplicate([]) == False) + diff --git a/two-sum/JoyJaewon.py b/two-sum/JoyJaewon.py new file mode 100644 index 000000000..cc5966f0d --- /dev/null +++ b/two-sum/JoyJaewon.py @@ -0,0 +1,33 @@ +''' +Brainstorm +- Brute force: double for-loop / recursion - O(N^2) +- Two Pointer: O(nlogn) - sorting +- Efficient approach: use hashmap to go through the array once O(N) + +Plan +1. Initialize the dictionary +2. Iterate over the array + 2-1. For each number, calculate the complement + 2-2. check if the complement exists in the dictionary + 2-3. Return the indices if it exists + 2-4. If not, add the current number and its index to the dictionary +''' + +def twoSum(nums, target): + memo = {} + for i in range(len(nums)): + diff = target - nums[i] + if diff in memo: + return [memo[diff], i] + memo[nums[i]] = i + +#TC:O(N), SC:O(N) + +#Normal case +print(twoSum([2, 7, 11, 15], 9) == [0, 1]) +print(twoSum([3, 2, 4], 6) == [1, 2]) + +#Edge case +print(twoSum([1, 2], 3) == [0, 1]) +print(twoSum([1, 5, 10], 20) == None) + diff --git a/valid-anagram/JoyJaewon.py b/valid-anagram/JoyJaewon.py new file mode 100644 index 000000000..e0dacab6a --- /dev/null +++ b/valid-anagram/JoyJaewon.py @@ -0,0 +1,39 @@ +''' +Brainstorm +- brute force: double for-loop O(N^2) +- efficient: use hash map O(N) + +plan +1. check the string lengths. Return false if different +2. Initialize the dictionary +3. Check the dictionary + 3-1. If all counts are zero, strings are anagrams. Return True + 3-2. If not, return False +''' +def isAnagram(s, t): + if len(s) != len(t): + return False + + count = {} + for char in s: + count[char] = count.get(char, 0) + 1 + + for char in t: + if char in count: + count[char] -= 1 + if count[char] < 0: + return False + else: + return False + + return all(x == 0 for x in count.values()) + +#TC: O(N), SC: O(N) + +#Normal case +print(isAnagram("anagram", "nagaram") == True) +print(isAnagram("rat", "car") == False) + +#Edge case +print(isAnagram("", "") == True) + diff --git a/valid-palindrome/JoyJaewon.py b/valid-palindrome/JoyJaewon.py new file mode 100644 index 000000000..bf7f7cfa3 --- /dev/null +++ b/valid-palindrome/JoyJaewon.py @@ -0,0 +1,39 @@ +''' +Brainstorm +- Brute force: double for-loop O(N^2) +- Efficient: two pointer O(N) + +Plan +1. Preprocess the input data (lowercase, remove non-alphanumeric char) +2. Use two pointers to check for palindrome +''' +#Version 1 +def isPalindrome(s): + filtered_chars = [c.lower() for c in s if c.isalnum()] + left, right = 0, len(filtered_chars) - 1 + + while left < right: + if filtered_chars[left] != filtered_chars[right]: + return False + left, right = left + 1, right - 1 + + return True + + +#Version 2 +def isPalindrome2(s): + filtered_chars = [c.lower() for c in s if c.isalnum()] + return filtered_chars == filtered_chars[::-1] + + +#TC: O(N), SC: O(N) + +#Normal case +print(isPalindrome("A man, a plan, a canal: Panama") == True) +print(isPalindrome("race a car") == False) + +#Edge case +print(isPalindrome("") == True) +print(isPalindrome(" ") == True) +print(isPalindrome("a.") == True) +